Zelda Classic Coverage Report


Directory: src/
File: src/guys.cpp
Date: 2022-12-14 01:59:18
Exec Total Coverage
Lines: 3212 11746 27.3%
Functions: 156 424 36.8%
Branches: 2489 14568 17.1%

Line Branch Exec Source
1 //--------------------------------------------------------
2 // Zelda Classic
3 // by Jeremy Craner, 1999-2000
4 //
5 // guys.cc
6 //
7 // "Guys" code (and other related stuff) for zelda.cc
8 //
9 //--------------------------------------------------------
10
11 #include "precompiled.h" //always first
12
13 #include <string.h>
14 #include <stdio.h>
15 #include "base/zc_alleg.h"
16 14 #include "guys.h"
17 #include "zelda.h"
18 #include "base/zsys.h"
19 #include "maps.h"
20 #include "hero.h"
21 #include "subscr.h"
22 #include "ffscript.h"
23 #include "gamedata.h"
24 #include "defdata.h"
25 #include "zscriptversion.h"
26 #include "particles.h"
27 #include "base/zc_math.h"
28 #include "slopes.h"
29 extern particle_list particles;
30
31 extern FFScript FFCore;
32 extern word item_doscript[256];
33 extern refInfo itemScriptData[256];
34 extern int32_t item_stack[256][MAX_SCRIPT_REGISTERS];
35 extern ZModule zcm;
36 extern HeroClass Hero;
37 extern sprite_list guys, items, Ewpns, Lwpns, Sitems, chainlinks, decorations;
38 extern zinitdata zinit;
39
40 int32_t repaircharge=0;
41 bool adjustmagic=false;
42 bool learnslash=false;
43 int32_t wallm_load_clk=0;
44 int32_t sle_x,sle_y,sle_cnt,sle_clk=0;
45 int32_t vhead=0;
46 int32_t guycarryingitem=0;
47
48 char *guy_string[eMAXGUYS];
49
50 void never_return(int32_t index);
51 void playLevelMusic();
52
53 // If an enemy is this far out of the playing field, just remove it.
54 #define OUTOFBOUNDS ((int32_t)y>((isSideViewGravity() && canfall(id))?192:352) || y<-176 || x<-256 || x > 512)
55 //#define NEWOUTOFBOUNDS ((int32_t)y>32767 || y<-32767 || x<-32767 || x > 32767)
56 #define IGNORE_SIDEVIEW_PLATFORMS (editorflags & ENEMY_FLAG14)
57 #define OFFGRID_ENEMY (editorflags & ENEMY_FLAG15)
58
59 4666 void do_fix(zfix& coord, int32_t val, bool nearest_half = false)
60 {
61 4666 int32_t c = coord.getInt();
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4666 times.
4666 if(nearest_half)
63 {
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4666 times.
4666 if (c < 0)
65 c -= val / 2;
66 4666 else c += (val/2);
67 4666 }
68 4666 c -= c % val;
69 4666 coord = c;
70 4666 }
71
72 bool NEWOUTOFBOUNDS(zfix x, zfix y, zfix z)
73 {
74 return
75 (
76 (((int32_t)y) > FFCore.enemy_removal_point[spriteremovalY2])
77 || (((int32_t)y) < FFCore.enemy_removal_point[spriteremovalY1])
78 || (((int32_t)x) < FFCore.enemy_removal_point[spriteremovalX1])
79 || (((int32_t)x) > FFCore.enemy_removal_point[spriteremovalX2])
80 || (((int32_t)z) < FFCore.enemy_removal_point[spriteremovalZ1])
81 || (((int32_t)z) > FFCore.enemy_removal_point[spriteremovalZ2])
82 );
83 }
84
85 namespace
86 {
87 int32_t trapConstantHorizontalID;
88 int32_t trapConstantVerticalID;
89 int32_t trapLOSHorizontalID;
90 int32_t trapLOSVerticalID;
91 int32_t trapLOS4WayID;
92
93 int32_t cornerTrapID;
94 int32_t centerTrapID;
95
96 int32_t rockID;
97 int32_t zoraID;
98 int32_t statueID;
99 }
100
101 18 void identifyCFEnemies()
102 {
103 18 trapConstantHorizontalID=-1;
104 18 trapConstantVerticalID=-1;
105 18 trapLOSHorizontalID=-1;
106 18 trapLOSVerticalID=-1;
107 18 trapLOS4WayID=-1;
108 18 cornerTrapID=-1;
109 18 centerTrapID=-1;
110 18 rockID=-1;
111 18 zoraID=-1;
112 18 statueID=-1;
113
114
2/2
✓ Branch 0 taken 9216 times.
✓ Branch 1 taken 18 times.
9234 for(int32_t i=0; i<eMAXGUYS; i++)
115 {
116
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&cmbflag_trph) && trapLOSHorizontalID==-1)
117 18 trapLOSHorizontalID=i;
118
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&cmbflag_trpv) && trapLOSVerticalID==-1)
119 18 trapLOSVerticalID=i;
120
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&cmbflag_trp4) && trapLOS4WayID==-1)
121 18 trapLOS4WayID=i;
122
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&cmbflag_trplr) && trapConstantHorizontalID==-1)
123 18 trapConstantHorizontalID=i;
124
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&cmbflag_trpud) && trapConstantVerticalID==-1)
125 18 trapConstantVerticalID=i;
126
127
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&eneflag_trap) && cornerTrapID==-1)
128 18 cornerTrapID=i;
129
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&eneflag_trp2) && centerTrapID==-1)
130 18 centerTrapID=i;
131
132
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&eneflag_rock) && rockID==-1)
133 18 rockID=i;
134
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&eneflag_zora) && zoraID==-1)
135 18 zoraID=i;
136
137
4/4
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 9195 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2 & eneflag_fire) && statueID==-1)
138 18 statueID=i;
139 9216 }
140 18 }
141
142 int32_t random_layer_enemy()
143 {
144 int32_t cnt=count_layer_enemies();
145
146 if(cnt==0)
147 {
148 return eNONE;
149 }
150
151 int32_t ret=zc_oldrand()%cnt;
152 cnt=0;
153
154 for(int32_t i=0; i<6; ++i)
155 {
156 if(tmpscr->layermap[i]!=0)
157 {
158 mapscr *layerscreen=&TheMaps[(tmpscr->layermap[i]-1)*MAPSCRS]+tmpscr->layerscreen[i];
159
160 for(int32_t j=0; j<10; ++j)
161 {
162 if(layerscreen->enemy[j]>0&&layerscreen->enemy[j]<MAXGUYS)
163 {
164 if(cnt==ret)
165 {
166 return layerscreen->enemy[j];
167 }
168
169 ++cnt;
170 }
171 }
172 }
173 }
174
175 return eNONE;
176 }
177
178 int32_t count_layer_enemies()
179 {
180 int32_t cnt=0;
181
182 for(int32_t i=0; i<6; ++i)
183 {
184 if(tmpscr->layermap[i]!=0)
185 {
186 mapscr *layerscreen=&TheMaps[(tmpscr->layermap[i]-1)*MAPSCRS]+tmpscr->layerscreen[i];
187
188 for(int32_t j=0; j<10; ++j)
189 {
190 if(layerscreen->enemy[j]!=0)
191 {
192 ++cnt;
193 }
194 }
195 }
196 }
197
198 return cnt;
199 }
200
201 1427 int32_t hero_on_wall()
202 {
203 1427 zfix lx = Hero.getX();
204 1427 zfix ly = Hero.getY();
205
206
207 //zprint2("hero_on_wall x is: %d\n", lx);
208 //zprint2("hero_on_wall y is: %d\n", ly);
209
210
4/4
✓ Branch 0 taken 1341 times.
✓ Branch 1 taken 86 times.
✓ Branch 2 taken 159 times.
✓ Branch 3 taken 1182 times.
1427 if(lx>=48 && lx<=192)
211 {
212
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1179 times.
1182 if(ly==32) return up+1;
213
214
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1178 times.
1179 if(ly==128) return down+1;
215 1178 }
216
217
4/4
✓ Branch 0 taken 1346 times.
✓ Branch 1 taken 77 times.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 1269 times.
1423 if(ly>=48 && ly<=112)
218 {
219
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1265 times.
1269 if(lx==32) return left+1;
220
221
2/2
✓ Branch 0 taken 1260 times.
✓ Branch 1 taken 5 times.
1265 if(lx==208) return right+1;
222 1260 }
223
224 1414 return 0;
225 1427 }
226
227 15042 bool tooclose(int32_t x,int32_t y,int32_t d)
228 {
229
2/2
✓ Branch 0 taken 11446 times.
✓ Branch 1 taken 3596 times.
15042 return (abs(int32_t(HeroX())-x)<d && abs(int32_t(HeroY())-y)<d);
230 }
231
232 23060 bool enemy::overpit(enemy *e)
233 {
234
2/2
✓ Branch 0 taken 23060 times.
✓ Branch 1 taken 276720 times.
299780 for ( int32_t q = 0; q < hxsz; ++q )
235 {
236
2/2
✓ Branch 0 taken 2213760 times.
✓ Branch 1 taken 276720 times.
2490480 for ( int32_t q = 0; q < hysz; ++q )
237 {
238 //check every pixel of the hitbox
239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2213760 times.
2213760 if ( ispitfall(x+q+hxofs, y+q+hyofs) )
240 {
241 //if the hitbox is over a pit, we can't land
242 return true;
243 }
244 2213760 }
245 276720 }
246 23060 return false;
247 23060 }
248
249 39466 bool enemy::shadow_overpit(enemy *e)
250 {
251
2/2
✓ Branch 0 taken 39466 times.
✓ Branch 1 taken 600184 times.
639650 for ( int32_t q = 0; q < hxsz; ++q )
252 {
253
2/2
✓ Branch 0 taken 8948752 times.
✓ Branch 1 taken 600184 times.
9548936 for ( int32_t q = 0; q < hysz; ++q )
254 {
255 //check every pixel of the hitbox
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8948752 times.
8948752 if ( ispitfall(x+q+hxofs, y+q+hyofs+hysz-2) )
257 {
258 //if the hitbox is over a pit, we can't land
259 return true;
260 }
261 8948752 }
262 600184 }
263 39466 return false;
264 39466 }
265
266 // Returns true iff a combo type or flag precludes enemy movement.
267 18808 bool enemy::groundblocked(int32_t dx, int32_t dy, bool isKB)
268 {
269
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18808 times.
18808 if(moveflags & FLAG_IGNORE_BLOCKFLAGS) return false;
270 18808 int32_t c = COMBOTYPE(dx,dy);
271
3/4
✓ Branch 0 taken 11750 times.
✓ Branch 1 taken 7058 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7058 times.
25866 bool pit_blocks = (!(moveflags & (FLAG_CAN_PITWALK|FLAG_ONLY_PITWALK)) && (!(moveflags & FLAG_CAN_PITFALL) || !isKB));
272
3/6
✓ Branch 0 taken 7058 times.
✓ Branch 1 taken 11750 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7058 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
18808 bool water_blocks = (!(moveflags & (FLAG_CAN_WATERWALK|FLAG_ONLY_WATERWALK|FLAG_ONLY_SHALLOW_WATERWALK)) && (!(moveflags & FLAG_CAN_WATERDROWN) || !isKB) && get_bit(quest_rules,qr_DROWN));
273
4/6
✓ Branch 0 taken 7092 times.
✓ Branch 1 taken 11716 times.
✓ Branch 2 taken 7092 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7092 times.
✗ Branch 5 not taken.
37616 return c==cPIT || c==cPITB || c==cPITC ||
274
4/6
✓ Branch 0 taken 7092 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7092 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5858 times.
✓ Branch 5 taken 1234 times.
7092 c==cPITD || c==cPITR || (pit_blocks && ispitfall(dx,dy)) ||
275 // Block enemies type and block enemies flags
276
2/2
✓ Branch 0 taken 7092 times.
✓ Branch 1 taken 5858 times.
1234 combo_class_buf[c].block_enemies&1 ||
277
2/4
✓ Branch 0 taken 7092 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7092 times.
✗ Branch 3 not taken.
7092 MAPFLAG(dx,dy)==mfNOENEMY || MAPCOMBOFLAG(dx,dy)==mfNOENEMY ||
278
2/4
✓ Branch 0 taken 7092 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7092 times.
✗ Branch 3 not taken.
7092 MAPFLAG(dx,dy)==mfNOGROUNDENEMY || MAPCOMBOFLAG(dx,dy)==mfNOGROUNDENEMY ||
279 // Check for ladder-only combos which aren't dried water
280
3/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 7024 times.
✓ Branch 2 taken 68 times.
✗ Branch 3 not taken.
14184 (combo_class_buf[c].ladder_pass&1 && !iswater_type(c)) ||
281 // Check for drownable water
282
3/4
✓ Branch 0 taken 1540 times.
✓ Branch 1 taken 5552 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1540 times.
7092 (water_blocks && !(isSideViewGravity()) && (iswaterex(MAPCOMBO(dx,dy), currmap, currscr, -1, dx, dy, false, false, true, false, false)));
283 7092 }
284
285 // Returns true iff enemy is floating and blocked by a combo type or flag.
286 44414 bool enemy::flyerblocked(int32_t dx, int32_t dy, int32_t special, bool isKB)
287 {
288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44414 times.
44414 if(moveflags & FLAG_IGNORE_BLOCKFLAGS) return false;
289
3/4
✓ Branch 0 taken 41293 times.
✓ Branch 1 taken 3121 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3121 times.
47535 bool pit_blocks = (!(moveflags & FLAG_CAN_PITWALK) && (!(moveflags & FLAG_CAN_PITFALL) || !isKB));
290
3/4
✓ Branch 0 taken 41293 times.
✓ Branch 1 taken 3121 times.
✓ Branch 2 taken 3121 times.
✗ Branch 3 not taken.
47535 bool water_blocks = (!(moveflags & FLAG_CAN_WATERWALK) && (!(moveflags & FLAG_CAN_WATERDROWN) || !isKB));
291
2/2
✓ Branch 0 taken 3138 times.
✓ Branch 1 taken 41276 times.
85690 return ((special==spw_floater)&&
292
2/2
✓ Branch 0 taken 41224 times.
✓ Branch 1 taken 52 times.
41276 ((COMBOTYPE(dx,dy)==cNOFLYZONE)||
293
1/2
✓ Branch 0 taken 41224 times.
✗ Branch 1 not taken.
41224 (combo_class_buf[COMBOTYPE(dx,dy)].block_enemies&4)||
294
1/2
✓ Branch 0 taken 41224 times.
✗ Branch 1 not taken.
41224 (MAPFLAG(dx,dy)==mfNOENEMY)||
295
1/2
✓ Branch 0 taken 41224 times.
✗ Branch 1 not taken.
41224 (MAPCOMBOFLAG(dx,dy)==mfNOENEMY)||
296
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 41224 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
82448 (water_blocks && iswaterex(MAPCOMBO(dx, dy), currmap, currscr, -1, dx,dy, false, false, true)) ||
297
1/2
✓ Branch 0 taken 41224 times.
✗ Branch 1 not taken.
41224 (pit_blocks && ispitfall(dx,dy))));
298 44414 }
299 // Returns true iff a combo type or flag precludes enemy movement.
300 6057 bool groundblocked(int32_t dx, int32_t dy, guydata const& gd)
301 {
302 6057 int32_t c = COMBOTYPE(dx,dy);
303 6057 bool pit_blocks = !(gd.moveflags & FLAG_CAN_PITWALK);
304
2/2
✓ Branch 0 taken 484 times.
✓ Branch 1 taken 5573 times.
6057 bool water_blocks = !(gd.moveflags & FLAG_CAN_WATERWALK) && get_bit(quest_rules,qr_DROWN);
305
3/6
✓ Branch 0 taken 6057 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6057 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6057 times.
✗ Branch 5 not taken.
23260 return c==cPIT || c==cPITB || c==cPITC ||
306
4/6
✓ Branch 0 taken 6057 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6057 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5573 times.
✓ Branch 5 taken 484 times.
6057 c==cPITD || c==cPITR || (pit_blocks && ispitfall(dx,dy)) ||
307 // Block enemies type and block enemies flags
308
2/2
✓ Branch 0 taken 6057 times.
✓ Branch 1 taken 5573 times.
484 combo_class_buf[c].block_enemies&1 ||
309
2/4
✓ Branch 0 taken 6057 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6057 times.
✗ Branch 3 not taken.
6057 MAPFLAG(dx,dy)==mfNOENEMY || MAPCOMBOFLAG(dx,dy)==mfNOENEMY ||
310
2/4
✓ Branch 0 taken 6057 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6057 times.
✗ Branch 3 not taken.
6057 MAPFLAG(dx,dy)==mfNOGROUNDENEMY || MAPCOMBOFLAG(dx,dy)==mfNOGROUNDENEMY ||
311 // Check for ladder-only combos which aren't dried water
312
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6057 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12114 (combo_class_buf[c].ladder_pass&1 && !iswater_type(c)) ||
313 // Check for drownable water
314
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 6047 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
6057 (water_blocks && !(isSideViewGravity()) && (iswaterex(MAPCOMBO(dx,dy), currmap, currscr, -1, dx, dy, false, false, true)));
315 }
316
317 // Returns true iff enemy is floating and blocked by a combo type or flag.
318 2517 bool flyerblocked(int32_t dx, int32_t dy, int32_t special, guydata const& gd)
319 {
320
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 bool pit_blocks = (!(gd.moveflags & FLAG_CAN_PITWALK) && !(gd.moveflags & FLAG_CAN_PITFALL));
321 2517 bool water_blocks = !(gd.moveflags & FLAG_CAN_WATERWALK);
322
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2517 times.
5034 return ((special==spw_floater)&&
323
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 ((COMBOTYPE(dx,dy)==cNOFLYZONE)||
324
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 (combo_class_buf[COMBOTYPE(dx,dy)].block_enemies&4)||
325
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 (MAPFLAG(dx,dy)==mfNOENEMY)||
326
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 (MAPCOMBOFLAG(dx,dy)==mfNOENEMY)||
327
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2517 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5034 (water_blocks && iswaterex(MAPCOMBO(dx,dy), currmap, currscr, -1, dx, dy, false, false, true)) ||
328
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 (pit_blocks && ispitfall(dx,dy))));
329 }
330
331 /**********************************/
332 /******* Enemy Base Class *******/
333 /**********************************/
334
335 /* ROM data flags
336
337 */
338
339 eFire::eFire(eFire const & other, bool new_script_uid, bool clear_parent_script_UID):
340 //Struct Element Type Purpose
341 //sprite(other),
342 enemy(other),
343 clk4(other.clk4),
344 shield(other.shield)
345
346 {
347
348 //arrays
349
350 if(other.scrmem)
351 {
352 alloc_scriptmem();
353 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
354
355 scrmem->scriptData = other.scrmem->scriptData;
356 }
357 else scrmem = NULL;
358 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
359 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
360
361 for(int32_t i=0; i<edefLAST255; i++)
362 defense[i]=other.defense[i];
363 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
364 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
365
366 if(new_script_uid)
367 {
368 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
369 }
370 if(clear_parent_script_UID)
371 {
372 parent_script_UID = 0;
373 }
374 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
375 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
376
377 for ( int32_t q = 0; q < 8; q++ )
378 {
379 initD[q] = other.initD[q];
380 weap_initiald[q] = other.weap_initiald[q];
381 }
382 for ( int32_t q = 0; q < 2; q++ )
383 {
384 initA[q] = other.initA[q];
385 weap_initiala[q] = other.weap_initiala[q];
386 }
387 }
388
389 eOther::eOther(eOther const & other, bool new_script_uid, bool clear_parent_script_UID):
390 //Struct Element Type Purpose
391 //sprite(other),
392 enemy(other),
393 clk4(other.clk4),
394 shield(other.shield)
395
396 {
397
398 //arrays
399
400 if(other.scrmem)
401 {
402 alloc_scriptmem();
403 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
404
405 scrmem->scriptData = other.scrmem->scriptData;
406 }
407 else scrmem = NULL;
408 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
409 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
410
411 for(int32_t i=0; i<edefLAST255; i++)
412 defense[i]=other.defense[i];
413 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
414 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
415
416 if(new_script_uid)
417 {
418 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
419 }
420 if(clear_parent_script_UID)
421 {
422 parent_script_UID = 0;
423 }
424 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
425 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
426
427 for ( int32_t q = 0; q < 8; q++ )
428 {
429 initD[q] = other.initD[q];
430 weap_initiald[q] = other.weap_initiald[q];
431 }
432 for ( int32_t q = 0; q < 2; q++ )
433 {
434 initA[q] = other.initA[q];
435 weap_initiala[q] = other.weap_initiala[q];
436 }
437 }
438
439
440
441
442 eScript::eScript(eScript const & other, bool new_script_uid, bool clear_parent_script_UID):
443 //Struct Element Type Purpose
444 //sprite(other),
445 enemy(other),
446 clk4(other.clk4),
447 shield(other.shield)
448
449 {
450
451 //arrays
452
453 if(other.scrmem)
454 {
455 alloc_scriptmem();
456 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
457
458 scrmem->scriptData = other.scrmem->scriptData;
459 }
460 else scrmem = NULL;
461 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
462 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
463
464 for(int32_t i=0; i<edefLAST255; i++)
465 defense[i]=other.defense[i];
466 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
467 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
468
469 if(new_script_uid)
470 {
471 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
472 }
473 if(clear_parent_script_UID)
474 {
475 parent_script_UID = 0;
476 }
477 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
478 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
479
480 for ( int32_t q = 0; q < 8; q++ )
481 {
482 initD[q] = other.initD[q];
483 weap_initiald[q] = other.weap_initiald[q];
484 }
485 for ( int32_t q = 0; q < 2; q++ )
486 {
487 initA[q] = other.initA[q];
488 weap_initiala[q] = other.weap_initiala[q];
489 }
490 }
491
492 eFriendly::eFriendly(eFriendly const & other, bool new_script_uid, bool clear_parent_script_UID):
493 //Struct Element Type Purpose
494 //sprite(other),
495 enemy(other),
496 clk4(other.clk4),
497 shield(other.shield)
498
499 {
500
501 //arrays
502
503 if(other.scrmem)
504 {
505 alloc_scriptmem();
506 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
507
508 scrmem->scriptData = other.scrmem->scriptData;
509 }
510 else scrmem = NULL;
511 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
512 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
513
514 for(int32_t i=0; i<edefLAST255; i++)
515 defense[i]=other.defense[i];
516 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
517 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
518
519 if(new_script_uid)
520 {
521 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
522 }
523 if(clear_parent_script_UID)
524 {
525 parent_script_UID = 0;
526 }
527 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
528 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
529
530 for ( int32_t q = 0; q < 8; q++ )
531 {
532 initD[q] = other.initD[q];
533 weap_initiald[q] = other.weap_initiald[q];
534 }
535 for ( int32_t q = 0; q < 2; q++ )
536 {
537 initA[q] = other.initA[q];
538 weap_initiala[q] = other.weap_initiala[q];
539 }
540 }
541
542 eGhini::eGhini(eGhini const & other, bool new_script_uid, bool clear_parent_script_UID):
543 //Struct Element Type Purpose
544 //sprite(other),
545 enemy(other),
546 clk4(other.clk4),
547 ox(other.ox),
548 oy(other.oy),
549 c(other.c)
550
551 {
552
553 //arrays
554
555 if(other.scrmem)
556 {
557 alloc_scriptmem();
558 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
559
560 scrmem->scriptData = other.scrmem->scriptData;
561 }
562 else scrmem = NULL;
563 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
564 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
565
566 for(int32_t i=0; i<edefLAST255; i++)
567 defense[i]=other.defense[i];
568 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
569 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
570
571 if(new_script_uid)
572 {
573 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
574 }
575 if(clear_parent_script_UID)
576 {
577 parent_script_UID = 0;
578 }
579 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
580 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
581
582 for ( int32_t q = 0; q < 8; q++ )
583 {
584 initD[q] = other.initD[q];
585 weap_initiald[q] = other.weap_initiald[q];
586 }
587 for ( int32_t q = 0; q < 2; q++ )
588 {
589 initA[q] = other.initA[q];
590 weap_initiala[q] = other.weap_initiala[q];
591 }
592 }
593
594 eTektite::eTektite(eTektite const & other, bool new_script_uid, bool clear_parent_script_UID):
595 //Struct Element Type Purpose
596 //sprite(other),
597 enemy(other),
598 old_y(other.old_y),
599 clk2start(other.clk2start),
600 cstart(other.cstart),
601 c(other.c)
602
603 {
604
605 //arrays
606
607 if(other.scrmem)
608 {
609 alloc_scriptmem();
610 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
611
612 scrmem->scriptData = other.scrmem->scriptData;
613 }
614 else scrmem = NULL;
615 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
616 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
617
618 for(int32_t i=0; i<edefLAST255; i++)
619 defense[i]=other.defense[i];
620 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
621 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
622
623 if(new_script_uid)
624 {
625 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
626 }
627 if(clear_parent_script_UID)
628 {
629 parent_script_UID = 0;
630 }
631 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
632 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
633
634 for ( int32_t q = 0; q < 8; q++ )
635 {
636 initD[q] = other.initD[q];
637 weap_initiald[q] = other.weap_initiald[q];
638 }
639 for ( int32_t q = 0; q < 2; q++ )
640 {
641 initA[q] = other.initA[q];
642 weap_initiala[q] = other.weap_initiala[q];
643 }
644 }
645
646 eItemFairy::eItemFairy(eItemFairy const & other, bool new_script_uid, bool clear_parent_script_UID):
647 //Struct Element Type Purpose
648 //sprite(other),
649 enemy(other)
650 {
651
652 //arrays
653
654 if(other.scrmem)
655 {
656 alloc_scriptmem();
657 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
658
659 scrmem->scriptData = other.scrmem->scriptData;
660 }
661 else scrmem = NULL;
662 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
663 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
664
665 for(int32_t i=0; i<edefLAST255; i++)
666 defense[i]=other.defense[i];
667 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
668 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
669
670 if(new_script_uid)
671 {
672 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
673 }
674 if(clear_parent_script_UID)
675 {
676 parent_script_UID = 0;
677 }
678 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
679 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
680
681 for ( int32_t q = 0; q < 8; q++ )
682 {
683 initD[q] = other.initD[q];
684 weap_initiald[q] = other.weap_initiald[q];
685 }
686 for ( int32_t q = 0; q < 2; q++ )
687 {
688 initA[q] = other.initA[q];
689 weap_initiala[q] = other.weap_initiala[q];
690 }
691 }
692
693 ePeahat::ePeahat(ePeahat const & other, bool new_script_uid, bool clear_parent_script_UID):
694 //Struct Element Type Purpose
695 //sprite(other),
696 enemy(other),
697 ox(other.ox),
698 oy(other.oy),
699 c(other.c)
700 {
701
702 //arrays
703
704 if(other.scrmem)
705 {
706 alloc_scriptmem();
707 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
708
709 scrmem->scriptData = other.scrmem->scriptData;
710 }
711 else scrmem = NULL;
712 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
713 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
714
715 for(int32_t i=0; i<edefLAST255; i++)
716 defense[i]=other.defense[i];
717 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
718 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
719
720 if(new_script_uid)
721 {
722 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
723 }
724 if(clear_parent_script_UID)
725 {
726 parent_script_UID = 0;
727 }
728 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
729 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
730
731 for ( int32_t q = 0; q < 8; q++ )
732 {
733 initD[q] = other.initD[q];
734 weap_initiald[q] = other.weap_initiald[q];
735 }
736 for ( int32_t q = 0; q < 2; q++ )
737 {
738 initA[q] = other.initA[q];
739 weap_initiala[q] = other.weap_initiala[q];
740 }
741 }
742
743 eLeever::eLeever(eLeever const & other, bool new_script_uid, bool clear_parent_script_UID):
744 //Struct Element Type Purpose
745 //sprite(other),
746 enemy(other),
747 temprule(other.temprule)
748 {
749
750 //arrays
751
752 if(other.scrmem)
753 {
754 alloc_scriptmem();
755 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
756
757 scrmem->scriptData = other.scrmem->scriptData;
758 }
759 else scrmem = NULL;
760 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
761 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
762
763 for(int32_t i=0; i<edefLAST255; i++)
764 defense[i]=other.defense[i];
765 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
766 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
767
768 if(new_script_uid)
769 {
770 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
771 }
772 if(clear_parent_script_UID)
773 {
774 parent_script_UID = 0;
775 }
776 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
777 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
778
779 for ( int32_t q = 0; q < 8; q++ )
780 {
781 initD[q] = other.initD[q];
782 weap_initiald[q] = other.weap_initiald[q];
783 }
784 for ( int32_t q = 0; q < 2; q++ )
785 {
786 initA[q] = other.initA[q];
787 weap_initiala[q] = other.weap_initiala[q];
788 }
789 }
790
791 eWallM::eWallM(eWallM const & other, bool new_script_uid, bool clear_parent_script_UID):
792 //Struct Element Type Purpose
793 //sprite(other),
794 enemy(other)
795 {
796
797 //arrays
798
799 if(other.scrmem)
800 {
801 alloc_scriptmem();
802 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
803
804 scrmem->scriptData = other.scrmem->scriptData;
805 }
806 else scrmem = NULL;
807 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
808 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
809
810 for(int32_t i=0; i<edefLAST255; i++)
811 defense[i]=other.defense[i];
812 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
813 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
814
815 if(new_script_uid)
816 {
817 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
818 }
819 if(clear_parent_script_UID)
820 {
821 parent_script_UID = 0;
822 }
823 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
824 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
825
826 for ( int32_t q = 0; q < 8; q++ )
827 {
828 initD[q] = other.initD[q];
829 weap_initiald[q] = other.weap_initiald[q];
830 }
831 for ( int32_t q = 0; q < 2; q++ )
832 {
833 initA[q] = other.initA[q];
834 weap_initiala[q] = other.weap_initiala[q];
835 }
836 }
837
838 eStalfos::eStalfos(eStalfos const & other, bool new_script_uid, bool clear_parent_script_UID):
839 //Struct Element Type Purpose
840 //sprite(other),
841 enemy(other),
842 clk4(other.clk4),
843 clk5(other.clk5),
844 fired(other.fired),
845 shield(other.shield),
846 dashing(other.dashing),
847 multishot(other.multishot),
848 fy(other.fy),
849 shadowdistance(other.shadowdistance)
850 {
851
852 //arrays
853
854 if(other.scrmem)
855 {
856 alloc_scriptmem();
857 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
858
859 scrmem->scriptData = other.scrmem->scriptData;
860 }
861 else scrmem = NULL;
862 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
863 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
864
865 for(int32_t i=0; i<edefLAST255; i++)
866 defense[i]=other.defense[i];
867 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
868 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
869
870 if(new_script_uid)
871 {
872 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
873 }
874 if(clear_parent_script_UID)
875 {
876 parent_script_UID = 0;
877 }
878 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
879 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
880
881 for ( int32_t q = 0; q < 8; q++ )
882 {
883 initD[q] = other.initD[q];
884 weap_initiald[q] = other.weap_initiald[q];
885 }
886 for ( int32_t q = 0; q < 2; q++ )
887 {
888 initA[q] = other.initA[q];
889 weap_initiala[q] = other.weap_initiala[q];
890 }
891 }
892
893 eZora::eZora(eZora const & other, bool new_script_uid, bool clear_parent_script_UID):
894 //Struct Element Type Purpose
895 //sprite(other),
896 enemy(other)
897 {
898
899 //arrays
900
901 if(other.scrmem)
902 {
903 alloc_scriptmem();
904 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
905
906 scrmem->scriptData = other.scrmem->scriptData;
907 }
908 else scrmem = NULL;
909 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
910 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
911
912 for(int32_t i=0; i<edefLAST255; i++)
913 defense[i]=other.defense[i];
914 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
915 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
916
917 if(new_script_uid)
918 {
919 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
920 }
921 if(clear_parent_script_UID)
922 {
923 parent_script_UID = 0;
924 }
925 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
926 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
927
928 for ( int32_t q = 0; q < 8; q++ )
929 {
930 initD[q] = other.initD[q];
931 weap_initiald[q] = other.weap_initiald[q];
932 }
933 for ( int32_t q = 0; q < 2; q++ )
934 {
935 initA[q] = other.initA[q];
936 weap_initiala[q] = other.weap_initiala[q];
937 }
938 }
939
940 eSpinTile::eSpinTile(eSpinTile const & other, bool new_script_uid, bool clear_parent_script_UID):
941 //Struct Element Type Purpose
942 //sprite(other),
943 enemy(other)
944 {
945
946 //arrays
947
948 if(other.scrmem)
949 {
950 alloc_scriptmem();
951 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
952
953 scrmem->scriptData = other.scrmem->scriptData;
954 }
955 else scrmem = NULL;
956 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
957 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
958
959 for(int32_t i=0; i<edefLAST255; i++)
960 defense[i]=other.defense[i];
961 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
962 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
963
964 if(new_script_uid)
965 {
966 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
967 }
968 if(clear_parent_script_UID)
969 {
970 parent_script_UID = 0;
971 }
972 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
973 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
974
975 for ( int32_t q = 0; q < 8; q++ )
976 {
977 initD[q] = other.initD[q];
978 weap_initiald[q] = other.weap_initiald[q];
979 }
980 for ( int32_t q = 0; q < 2; q++ )
981 {
982 initA[q] = other.initA[q];
983 weap_initiala[q] = other.weap_initiala[q];
984 }
985 }
986
987 eNPC::eNPC(eNPC const & other, bool new_script_uid, bool clear_parent_script_UID):
988 //Struct Element Type Purpose
989 //sprite(other),
990 enemy(other)
991 {
992
993 //arrays
994
995 if(other.scrmem)
996 {
997 alloc_scriptmem();
998 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
999
1000 scrmem->scriptData = other.scrmem->scriptData;
1001 }
1002 else scrmem = NULL;
1003 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1004 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1005
1006 for(int32_t i=0; i<edefLAST255; i++)
1007 defense[i]=other.defense[i];
1008 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1009 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1010
1011 if(new_script_uid)
1012 {
1013 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1014 }
1015 if(clear_parent_script_UID)
1016 {
1017 parent_script_UID = 0;
1018 }
1019 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1020 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1021
1022 for ( int32_t q = 0; q < 8; q++ )
1023 {
1024 initD[q] = other.initD[q];
1025 weap_initiald[q] = other.weap_initiald[q];
1026 }
1027 for ( int32_t q = 0; q < 2; q++ )
1028 {
1029 initA[q] = other.initA[q];
1030 weap_initiala[q] = other.weap_initiala[q];
1031 }
1032 }
1033
1034 eTrigger::eTrigger(eTrigger const & other, bool new_script_uid, bool clear_parent_script_UID):
1035 //Struct Element Type Purpose
1036 //sprite(other),
1037 enemy(other)
1038 {
1039
1040 //arrays
1041
1042 if(other.scrmem)
1043 {
1044 alloc_scriptmem();
1045 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1046
1047 scrmem->scriptData = other.scrmem->scriptData;
1048 }
1049 else scrmem = NULL;
1050 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1051 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1052
1053 for(int32_t i=0; i<edefLAST255; i++)
1054 defense[i]=other.defense[i];
1055 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1056 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1057
1058 if(new_script_uid)
1059 {
1060 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1061 }
1062 if(clear_parent_script_UID)
1063 {
1064 parent_script_UID = 0;
1065 }
1066 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1067 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1068
1069 for ( int32_t q = 0; q < 8; q++ )
1070 {
1071 initD[q] = other.initD[q];
1072 weap_initiald[q] = other.weap_initiald[q];
1073 }
1074 for ( int32_t q = 0; q < 2; q++ )
1075 {
1076 initA[q] = other.initA[q];
1077 weap_initiala[q] = other.weap_initiala[q];
1078 }
1079 }
1080
1081 eProjectile::eProjectile(eProjectile const & other, bool new_script_uid, bool clear_parent_script_UID):
1082 //Struct Element Type Purpose
1083 //sprite(other),
1084 enemy(other),
1085 minRange(other.minRange)
1086 {
1087
1088 //arrays
1089
1090 if(other.scrmem)
1091 {
1092 alloc_scriptmem();
1093 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1094
1095 scrmem->scriptData = other.scrmem->scriptData;
1096 }
1097 else scrmem = NULL;
1098 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1099 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1100
1101 for(int32_t i=0; i<edefLAST255; i++)
1102 defense[i]=other.defense[i];
1103 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1104 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1105
1106 if(new_script_uid)
1107 {
1108 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1109 }
1110 if(clear_parent_script_UID)
1111 {
1112 parent_script_UID = 0;
1113 }
1114 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1115 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1116
1117 for ( int32_t q = 0; q < 8; q++ )
1118 {
1119 initD[q] = other.initD[q];
1120 weap_initiald[q] = other.weap_initiald[q];
1121 }
1122 for ( int32_t q = 0; q < 2; q++ )
1123 {
1124 initA[q] = other.initA[q];
1125 weap_initiala[q] = other.weap_initiala[q];
1126 }
1127 }
1128
1129 eBoulder::eBoulder(eBoulder const & other, bool new_script_uid, bool clear_parent_script_UID):
1130 //Struct Element Type Purpose
1131 //sprite(other),
1132 enemy(other)
1133 {
1134
1135 //arrays
1136
1137 if(other.scrmem)
1138 {
1139 alloc_scriptmem();
1140 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1141
1142 scrmem->scriptData = other.scrmem->scriptData;
1143 }
1144 else scrmem = NULL;
1145 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1146 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1147
1148 for(int32_t i=0; i<edefLAST255; i++)
1149 defense[i]=other.defense[i];
1150 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1151 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1152
1153 if(new_script_uid)
1154 {
1155 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1156 }
1157 if(clear_parent_script_UID)
1158 {
1159 parent_script_UID = 0;
1160 }
1161 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1162 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1163
1164 for ( int32_t q = 0; q < 8; q++ )
1165 {
1166 initD[q] = other.initD[q];
1167 weap_initiald[q] = other.weap_initiald[q];
1168 }
1169 for ( int32_t q = 0; q < 2; q++ )
1170 {
1171 initA[q] = other.initA[q];
1172 weap_initiala[q] = other.weap_initiala[q];
1173 }
1174 }
1175
1176 eRock::eRock(eRock const & other, bool new_script_uid, bool clear_parent_script_UID):
1177 //Struct Element Type Purpose
1178 //sprite(other),
1179 enemy(other)
1180 {
1181
1182 //arrays
1183
1184 if(other.scrmem)
1185 {
1186 alloc_scriptmem();
1187 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1188
1189 scrmem->scriptData = other.scrmem->scriptData;
1190 }
1191 else scrmem = NULL;
1192 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1193 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1194
1195 for(int32_t i=0; i<edefLAST255; i++)
1196 defense[i]=other.defense[i];
1197 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1198 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1199
1200 if(new_script_uid)
1201 {
1202 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1203 }
1204 if(clear_parent_script_UID)
1205 {
1206 parent_script_UID = 0;
1207 }
1208 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1209 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1210
1211 for ( int32_t q = 0; q < 8; q++ )
1212 {
1213 initD[q] = other.initD[q];
1214 weap_initiald[q] = other.weap_initiald[q];
1215 }
1216 for ( int32_t q = 0; q < 2; q++ )
1217 {
1218 initA[q] = other.initA[q];
1219 weap_initiala[q] = other.weap_initiala[q];
1220 }
1221 }
1222
1223 eTrap2::eTrap2(eTrap2 const & other, bool new_script_uid, bool clear_parent_script_UID):
1224 //Struct Element Type Purpose
1225 //sprite(other),
1226 enemy(other)
1227 {
1228
1229 //arrays
1230
1231 if(other.scrmem)
1232 {
1233 alloc_scriptmem();
1234 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1235
1236 scrmem->scriptData = other.scrmem->scriptData;
1237 }
1238 else scrmem = NULL;
1239 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1240 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1241
1242 for(int32_t i=0; i<edefLAST255; i++)
1243 defense[i]=other.defense[i];
1244 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1245 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1246
1247 if(new_script_uid)
1248 {
1249 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1250 }
1251 if(clear_parent_script_UID)
1252 {
1253 parent_script_UID = 0;
1254 }
1255 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1256 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1257
1258 for ( int32_t q = 0; q < 8; q++ )
1259 {
1260 initD[q] = other.initD[q];
1261 weap_initiald[q] = other.weap_initiald[q];
1262 }
1263 for ( int32_t q = 0; q < 2; q++ )
1264 {
1265 initA[q] = other.initA[q];
1266 weap_initiala[q] = other.weap_initiala[q];
1267 }
1268 }
1269
1270 eTrap::eTrap(eTrap const & other, bool new_script_uid, bool clear_parent_script_UID):
1271 //Struct Element Type Purpose
1272 //sprite(other),
1273 enemy(other),
1274 ox(other.ox),
1275 oy(other.oy)
1276 {
1277
1278 //arrays
1279
1280 if(other.scrmem)
1281 {
1282 alloc_scriptmem();
1283 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1284
1285 scrmem->scriptData = other.scrmem->scriptData;
1286 }
1287 else scrmem = NULL;
1288 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1289 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1290
1291 for(int32_t i=0; i<edefLAST255; i++)
1292 defense[i]=other.defense[i];
1293 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1294 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1295
1296 if(new_script_uid)
1297 {
1298 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1299 }
1300 if(clear_parent_script_UID)
1301 {
1302 parent_script_UID = 0;
1303 }
1304 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1305 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1306
1307 for ( int32_t q = 0; q < 8; q++ )
1308 {
1309 initD[q] = other.initD[q];
1310 weap_initiald[q] = other.weap_initiald[q];
1311 }
1312 for ( int32_t q = 0; q < 2; q++ )
1313 {
1314 initA[q] = other.initA[q];
1315 weap_initiala[q] = other.weap_initiala[q];
1316 }
1317 }
1318
1319
1320
1321
1322 eKeese::eKeese(eKeese const & other, bool new_script_uid, bool clear_parent_script_UID):
1323 //Struct Element Type Purpose
1324 //sprite(other),
1325 enemy(other),
1326 ox(other.ox),
1327 c(other.c),
1328 clk4(other.clk4),
1329 oy(other.oy)
1330 {
1331
1332 //arrays
1333
1334 if(other.scrmem)
1335 {
1336 alloc_scriptmem();
1337 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1338
1339 scrmem->scriptData = other.scrmem->scriptData;
1340 }
1341 else scrmem = NULL;
1342 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1343 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1344
1345 for(int32_t i=0; i<edefLAST255; i++)
1346 defense[i]=other.defense[i];
1347 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1348 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1349
1350 if(new_script_uid)
1351 {
1352 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1353 }
1354 if(clear_parent_script_UID)
1355 {
1356 parent_script_UID = 0;
1357 }
1358 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1359 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1360
1361 for ( int32_t q = 0; q < 8; q++ )
1362 {
1363 initD[q] = other.initD[q];
1364 weap_initiald[q] = other.weap_initiald[q];
1365 }
1366 for ( int32_t q = 0; q < 2; q++ )
1367 {
1368 initA[q] = other.initA[q];
1369 weap_initiala[q] = other.weap_initiala[q];
1370 }
1371 }
1372
1373 eWizzrobe::eWizzrobe(eWizzrobe const & other, bool new_script_uid, bool clear_parent_script_UID):
1374 //Struct Element Type Purpose
1375 //sprite(other),
1376 enemy(other),
1377 charging(other.charging),
1378 firing(other.firing),
1379 fclk(other.fclk)
1380 {
1381
1382 //arrays
1383
1384 if(other.scrmem)
1385 {
1386 alloc_scriptmem();
1387 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1388
1389 scrmem->scriptData = other.scrmem->scriptData;
1390 }
1391 else scrmem = NULL;
1392 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1393 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1394
1395 for(int32_t i=0; i<edefLAST255; i++)
1396 defense[i]=other.defense[i];
1397 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1398 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1399
1400 if(new_script_uid)
1401 {
1402 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1403 }
1404 if(clear_parent_script_UID)
1405 {
1406 parent_script_UID = 0;
1407 }
1408 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1409 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1410
1411 for ( int32_t q = 0; q < 8; q++ )
1412 {
1413 initD[q] = other.initD[q];
1414 weap_initiald[q] = other.weap_initiald[q];
1415 }
1416 for ( int32_t q = 0; q < 2; q++ )
1417 {
1418 initA[q] = other.initA[q];
1419 weap_initiala[q] = other.weap_initiala[q];
1420 }
1421 }
1422
1423 eDodongo::eDodongo(eDodongo const & other, bool new_script_uid, bool clear_parent_script_UID):
1424 //Struct Element Type Purpose
1425 //sprite(other),
1426 enemy(other)
1427 {
1428
1429 //arrays
1430
1431 if(other.scrmem)
1432 {
1433 alloc_scriptmem();
1434 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1435
1436 scrmem->scriptData = other.scrmem->scriptData;
1437 }
1438 else scrmem = NULL;
1439 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1440 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1441
1442 for(int32_t i=0; i<edefLAST255; i++)
1443 defense[i]=other.defense[i];
1444 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1445 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1446
1447 if(new_script_uid)
1448 {
1449 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1450 }
1451 if(clear_parent_script_UID)
1452 {
1453 parent_script_UID = 0;
1454 }
1455 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1456 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1457
1458 for ( int32_t q = 0; q < 8; q++ )
1459 {
1460 initD[q] = other.initD[q];
1461 weap_initiald[q] = other.weap_initiald[q];
1462 }
1463 for ( int32_t q = 0; q < 2; q++ )
1464 {
1465 initA[q] = other.initA[q];
1466 weap_initiala[q] = other.weap_initiala[q];
1467 }
1468 }
1469
1470 eDodongo2::eDodongo2(eDodongo2 const & other, bool new_script_uid, bool clear_parent_script_UID):
1471 //Struct Element Type Purpose
1472 //sprite(other),
1473 enemy(other),
1474 previous_dir(other.previous_dir)
1475 {
1476
1477 //arrays
1478
1479 if(other.scrmem)
1480 {
1481 alloc_scriptmem();
1482 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1483
1484 scrmem->scriptData = other.scrmem->scriptData;
1485 }
1486 else scrmem = NULL;
1487 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1488 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1489
1490 for(int32_t i=0; i<edefLAST255; i++)
1491 defense[i]=other.defense[i];
1492 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1493 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1494
1495 if(new_script_uid)
1496 {
1497 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1498 }
1499 if(clear_parent_script_UID)
1500 {
1501 parent_script_UID = 0;
1502 }
1503 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1504 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1505
1506 for ( int32_t q = 0; q < 8; q++ )
1507 {
1508 initD[q] = other.initD[q];
1509 weap_initiald[q] = other.weap_initiald[q];
1510 }
1511 for ( int32_t q = 0; q < 2; q++ )
1512 {
1513 initA[q] = other.initA[q];
1514 weap_initiala[q] = other.weap_initiala[q];
1515 }
1516 }
1517
1518 eAquamentus::eAquamentus(eAquamentus const & other, bool new_script_uid, bool clear_parent_script_UID):
1519 //Struct Element Type Purpose
1520 //sprite(other),
1521 enemy(other),
1522 fbx(other.fbx),
1523 clk4(other.clk4)
1524 {
1525
1526 //arrays
1527
1528 if(other.scrmem)
1529 {
1530 alloc_scriptmem();
1531 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1532
1533 scrmem->scriptData = other.scrmem->scriptData;
1534 }
1535 else scrmem = NULL;
1536 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1537 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1538
1539 for(int32_t i=0; i<edefLAST255; i++)
1540 defense[i]=other.defense[i];
1541 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1542 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1543
1544 if(new_script_uid)
1545 {
1546 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1547 }
1548 if(clear_parent_script_UID)
1549 {
1550 parent_script_UID = 0;
1551 }
1552 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1553 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1554
1555 for ( int32_t q = 0; q < 8; q++ )
1556 {
1557 initD[q] = other.initD[q];
1558 weap_initiald[q] = other.weap_initiald[q];
1559 }
1560 for ( int32_t q = 0; q < 2; q++ )
1561 {
1562 initA[q] = other.initA[q];
1563 weap_initiala[q] = other.weap_initiala[q];
1564 }
1565 }
1566
1567 eGohma::eGohma(eGohma const & other, bool new_script_uid, bool clear_parent_script_UID):
1568 //Struct Element Type Purpose
1569 //sprite(other),
1570 enemy(other),
1571 clk4(other.clk4)
1572 {
1573
1574 //arrays
1575
1576 if(other.scrmem)
1577 {
1578 alloc_scriptmem();
1579 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1580
1581 scrmem->scriptData = other.scrmem->scriptData;
1582 }
1583 else scrmem = NULL;
1584 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1585 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1586
1587 for(int32_t i=0; i<edefLAST255; i++)
1588 defense[i]=other.defense[i];
1589 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1590 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1591
1592 if(new_script_uid)
1593 {
1594 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1595 }
1596 if(clear_parent_script_UID)
1597 {
1598 parent_script_UID = 0;
1599 }
1600 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1601 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1602
1603 for ( int32_t q = 0; q < 8; q++ )
1604 {
1605 initD[q] = other.initD[q];
1606 weap_initiald[q] = other.weap_initiald[q];
1607 }
1608 for ( int32_t q = 0; q < 2; q++ )
1609 {
1610 initA[q] = other.initA[q];
1611 weap_initiala[q] = other.weap_initiala[q];
1612 }
1613 }
1614
1615 eLilDig::eLilDig(eLilDig const & other, bool new_script_uid, bool clear_parent_script_UID):
1616 //Struct Element Type Purpose
1617 //sprite(other),
1618 enemy(other)
1619 {
1620
1621 //arrays
1622
1623 if(other.scrmem)
1624 {
1625 alloc_scriptmem();
1626 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1627
1628 scrmem->scriptData = other.scrmem->scriptData;
1629 }
1630 else scrmem = NULL;
1631 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1632 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1633
1634 for(int32_t i=0; i<edefLAST255; i++)
1635 defense[i]=other.defense[i];
1636 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1637 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1638
1639 if(new_script_uid)
1640 {
1641 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1642 }
1643 if(clear_parent_script_UID)
1644 {
1645 parent_script_UID = 0;
1646 }
1647 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1648 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1649
1650 for ( int32_t q = 0; q < 8; q++ )
1651 {
1652 initD[q] = other.initD[q];
1653 weap_initiald[q] = other.weap_initiald[q];
1654 }
1655 for ( int32_t q = 0; q < 2; q++ )
1656 {
1657 initA[q] = other.initA[q];
1658 weap_initiala[q] = other.weap_initiala[q];
1659 }
1660 }
1661
1662 eBigDig::eBigDig(eBigDig const & other, bool new_script_uid, bool clear_parent_script_UID):
1663 //Struct Element Type Purpose
1664 //sprite(other),
1665 enemy(other)
1666 {
1667
1668 //arrays
1669
1670 if(other.scrmem)
1671 {
1672 alloc_scriptmem();
1673 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1674
1675 scrmem->scriptData = other.scrmem->scriptData;
1676 }
1677 else scrmem = NULL;
1678 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1679 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1680
1681 for(int32_t i=0; i<edefLAST255; i++)
1682 defense[i]=other.defense[i];
1683 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1684 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1685
1686 if(new_script_uid)
1687 {
1688 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1689 }
1690 if(clear_parent_script_UID)
1691 {
1692 parent_script_UID = 0;
1693 }
1694 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1695 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1696
1697 for ( int32_t q = 0; q < 8; q++ )
1698 {
1699 initD[q] = other.initD[q];
1700 weap_initiald[q] = other.weap_initiald[q];
1701 }
1702 for ( int32_t q = 0; q < 2; q++ )
1703 {
1704 initA[q] = other.initA[q];
1705 weap_initiala[q] = other.weap_initiala[q];
1706 }
1707 }
1708
1709 eGanon::eGanon(eGanon const & other, bool new_script_uid, bool clear_parent_script_UID):
1710 //Struct Element Type Purpose
1711 //sprite(other),
1712 enemy(other),
1713 Stunclk(other.Stunclk)
1714
1715 {
1716
1717 //arrays
1718
1719 if(other.scrmem)
1720 {
1721 alloc_scriptmem();
1722 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1723
1724 scrmem->scriptData = other.scrmem->scriptData;
1725 }
1726 else scrmem = NULL;
1727 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1728 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1729
1730 for(int32_t i=0; i<edefLAST255; i++)
1731 defense[i]=other.defense[i];
1732 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1733 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1734
1735 if(new_script_uid)
1736 {
1737 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1738 }
1739 if(clear_parent_script_UID)
1740 {
1741 parent_script_UID = 0;
1742 }
1743 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1744 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1745
1746 for ( int32_t q = 0; q < 8; q++ )
1747 {
1748 initD[q] = other.initD[q];
1749 weap_initiald[q] = other.weap_initiald[q];
1750 }
1751 for ( int32_t q = 0; q < 2; q++ )
1752 {
1753 initA[q] = other.initA[q];
1754 weap_initiala[q] = other.weap_initiala[q];
1755 }
1756 }
1757
1758 eMoldorm::eMoldorm(eMoldorm const & other, bool new_script_uid, bool clear_parent_script_UID):
1759 //Struct Element Type Purpose
1760 //sprite(other),
1761 enemy(other),
1762 segcnt(other.segcnt),
1763 segid(other.segid)
1764
1765 {
1766
1767 //arrays
1768
1769 if(other.scrmem)
1770 {
1771 alloc_scriptmem();
1772 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1773
1774 scrmem->scriptData = other.scrmem->scriptData;
1775 }
1776 else scrmem = NULL;
1777 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1778 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1779
1780 for(int32_t i=0; i<edefLAST255; i++)
1781 defense[i]=other.defense[i];
1782 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1783 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1784
1785 if(new_script_uid)
1786 {
1787 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1788 }
1789 if(clear_parent_script_UID)
1790 {
1791 parent_script_UID = 0;
1792 }
1793 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1794 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1795
1796 for ( int32_t q = 0; q < 8; q++ )
1797 {
1798 initD[q] = other.initD[q];
1799 weap_initiald[q] = other.weap_initiald[q];
1800 }
1801 for ( int32_t q = 0; q < 2; q++ )
1802 {
1803 initA[q] = other.initA[q];
1804 weap_initiala[q] = other.weap_initiala[q];
1805 }
1806 }
1807
1808 esMoldorm::esMoldorm(esMoldorm const & other, bool new_script_uid, bool clear_parent_script_UID):
1809 //Struct Element Type Purpose
1810 //sprite(other),
1811 enemy(other),
1812 parentclk(other.parentclk)
1813 {
1814
1815 //arrays
1816
1817 if(other.scrmem)
1818 {
1819 alloc_scriptmem();
1820 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1821
1822 scrmem->scriptData = other.scrmem->scriptData;
1823 }
1824 else scrmem = NULL;
1825 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1826 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1827
1828 for(int32_t i=0; i<edefLAST255; i++)
1829 defense[i]=other.defense[i];
1830 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1831 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1832
1833 if(new_script_uid)
1834 {
1835 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1836 }
1837 if(clear_parent_script_UID)
1838 {
1839 parent_script_UID = 0;
1840 }
1841 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1842 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1843
1844 for ( int32_t q = 0; q < 8; q++ )
1845 {
1846 initD[q] = other.initD[q];
1847 weap_initiald[q] = other.weap_initiald[q];
1848 }
1849 for ( int32_t q = 0; q < 2; q++ )
1850 {
1851 initA[q] = other.initA[q];
1852 weap_initiala[q] = other.weap_initiala[q];
1853 }
1854 }
1855 /*
1856 eManhandla::eManhandla(eManhandla const & other, bool new_script_uid, bool clear_parent_script_UID):
1857 //Struct Element Type Purpose
1858 //sprite(other),
1859 enemy(other),
1860 armcnt(armcnt),
1861 adjusted(adjusted),
1862 arm[0](arm[0]),
1863 arm[1](arm[1]),
1864 arm[2](arm[2]),
1865 arm[3](arm[3]),
1866 arm[4](arm[4]),
1867 arm[5](arm[5]),
1868 arm[6](arm[6]),
1869 arm[7](arm[7])
1870 {
1871
1872 //arrays
1873 if(other.scrmem)
1874 {
1875 alloc_scriptmem();
1876 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1877
1878 scrmem->scriptData = other.scrmem->scriptData;
1879 }
1880 else scrmem = NULL;
1881 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1882 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1883
1884 for(int32_t i=0; i<edefLAST255; i++)
1885 defense[i]=other.defense[i];
1886 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1887 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1888
1889 if(new_script_uid)
1890 {
1891 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1892 }
1893 if(clear_parent_script_UID)
1894 {
1895 parent_script_UID = 0;
1896 }
1897 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1898 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1899
1900 for ( int32_t q = 0; q < 8; q++ )
1901 {
1902 initD[q] = other.initD[q];
1903 weap_initiald[q] = other.weap_initiald[q];
1904 }
1905 for ( int32_t q = 0; q < 2; q++ )
1906 {
1907 initA[q] = other.initA[q];
1908 weap_initiala[q] = other.weap_initiala[q];
1909 }
1910 }
1911
1912 esManhandla::esManhandla(esManhandla const & other, bool new_script_uid, bool clear_parent_script_UID):
1913 //Struct Element Type Purpose
1914 //sprite(other),
1915 enemy(other)
1916 {
1917
1918 //arrays
1919 if(other.scrmem)
1920 {
1921 alloc_scriptmem();
1922 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1923
1924 scrmem->scriptData = other.scrmem->scriptData;
1925 }
1926 else scrmem = NULL;
1927 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1928 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1929
1930 for(int32_t i=0; i<edefLAST255; i++)
1931 defense[i]=other.defense[i];
1932 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1933 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1934
1935 if(new_script_uid)
1936 {
1937 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1938 }
1939 if(clear_parent_script_UID)
1940 {
1941 parent_script_UID = 0;
1942 }
1943 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1944 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1945
1946 for ( int32_t q = 0; q < 8; q++ )
1947 {
1948 initD[q] = other.initD[q];
1949 weap_initiald[q] = other.weap_initiald[q];
1950 }
1951 for ( int32_t q = 0; q < 2; q++ )
1952 {
1953 initA[q] = other.initA[q];
1954 weap_initiala[q] = other.weap_initiala[q];
1955 }
1956 }
1957
1958 eGleeok::eGleeok(eGleeok const & other, bool new_script_uid, bool clear_parent_script_UID):
1959 //Struct Element Type Purpose
1960 //sprite(other),
1961 enemy(other),
1962 flameclk(flameclk),
1963 flamehead(flamehead),
1964 necktile(necktile)
1965
1966 {
1967
1968 //arrays
1969
1970 if(other.scrmem)
1971 {
1972 alloc_scriptmem();
1973 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1974
1975 scrmem->scriptData = other.scrmem->scriptData;
1976 }
1977 else scrmem = NULL;
1978 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1979 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1980
1981 for(int32_t i=0; i<edefLAST255; i++)
1982 defense[i]=other.defense[i];
1983 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1984 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1985
1986 if(new_script_uid)
1987 {
1988 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1989 }
1990 if(clear_parent_script_UID)
1991 {
1992 parent_script_UID = 0;
1993 }
1994 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1995 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1996
1997 for ( int32_t q = 0; q < 8; q++ )
1998 {
1999 initD[q] = other.initD[q];
2000 weap_initiald[q] = other.weap_initiald[q];
2001 }
2002 for ( int32_t q = 0; q < 2; q++ )
2003 {
2004 initA[q] = other.initA[q];
2005 weap_initiala[q] = other.weap_initiala[q];
2006 }
2007 }
2008
2009 esGleeok::esGleeok(esGleeok const & other, bool new_script_uid, bool clear_parent_script_UID):
2010 //Struct Element Type Purpose
2011 //sprite(other),
2012 enemy(other),
2013 headtile(headtile),
2014 flyingheadtile(flyingheadtile),
2015 necktile(necktile),
2016 xoffset(xoffset),
2017 yoffset(yoffset),
2018 nx(nx),
2019 ny(ny),
2020 nxoffset(nxoffset),
2021 nyoffset(nyoffset),
2022 parent(parent)
2023
2024 {
2025
2026 //arrays
2027
2028 if(other.scrmem)
2029 {
2030 alloc_scriptmem();
2031 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2032
2033 scrmem->scriptData = other.scrmem->scriptData;
2034 }
2035 else scrmem = NULL;
2036 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2037 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2038
2039 //for ( int32_t q = 0; q < 255; q++ )
2040 //{
2041 // nx[q] = other.nx[q];
2042 // ny[q] = other.ny[q];
2043 // nxoffset[q] = other.nxoffset[q];
2044 // nyoffset[q] = other.nyoffset[q];
2045 //}
2046
2047 for(int32_t i=0; i<edefLAST255; i++)
2048 defense[i]=other.defense[i];
2049 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2050 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2051
2052 if(new_script_uid)
2053 {
2054 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2055 }
2056 if(clear_parent_script_UID)
2057 {
2058 parent_script_UID = 0;
2059 }
2060 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2061 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2062
2063 for ( int32_t q = 0; q < 8; q++ )
2064 {
2065 initD[q] = other.initD[q];
2066 weap_initiald[q] = other.weap_initiald[q];
2067 }
2068 for ( int32_t q = 0; q < 2; q++ )
2069 {
2070 initA[q] = other.initA[q];
2071 weap_initiala[q] = other.weap_initiala[q];
2072 }
2073 }
2074
2075 ePatra::ePatra(ePatra const & other, bool new_script_uid, bool clear_parent_script_UID):
2076 //Struct Element Type Purpose
2077 //sprite(other),
2078 enemy(other),
2079 flycnt(flycnt),
2080 flycnt2(flycnt2),
2081 loopcnt(loopcnt),
2082 lookat(lookat),
2083 circle_x(circle_x),
2084 circle_y(circle_y),
2085 temp_x(temp_x),
2086 temp_y(temp_y),
2087 adjusted(adjusted)
2088
2089 {
2090
2091 //arrays
2092
2093 if(other.scrmem)
2094 {
2095 alloc_scriptmem();
2096 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2097
2098 scrmem->scriptData = other.scrmem->scriptData;
2099 }
2100 else scrmem = NULL;
2101 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2102 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2103
2104 for(int32_t i=0; i<edefLAST255; i++)
2105 defense[i]=other.defense[i];
2106 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2107 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2108
2109 if(new_script_uid)
2110 {
2111 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2112 }
2113 if(clear_parent_script_UID)
2114 {
2115 parent_script_UID = 0;
2116 }
2117 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2118 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2119
2120 for ( int32_t q = 0; q < 8; q++ )
2121 {
2122 initD[q] = other.initD[q];
2123 weap_initiald[q] = other.weap_initiald[q];
2124 }
2125 for ( int32_t q = 0; q < 2; q++ )
2126 {
2127 initA[q] = other.initA[q];
2128 weap_initiala[q] = other.weap_initiala[q];
2129 }
2130 }
2131
2132 ePatraBS::ePatraBS(ePatraBS const & other, bool new_script_uid, bool clear_parent_script_UID):
2133 //Struct Element Type Purpose
2134 //sprite(other),
2135 enemy(other),
2136 flycnt(flycnt),
2137 flycnt2(flycnt2),
2138 loopcnt(loopcnt),
2139 lookat(lookat),
2140 adjusted(adjusted)
2141
2142 {
2143
2144 //arrays
2145
2146 if(other.scrmem)
2147 {
2148 alloc_scriptmem();
2149 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2150
2151 scrmem->scriptData = other.scrmem->scriptData;
2152 }
2153 else scrmem = NULL;
2154 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2155 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2156
2157 for(int32_t i=0; i<edefLAST255; i++)
2158 defense[i]=other.defense[i];
2159 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2160 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2161
2162 if(new_script_uid)
2163 {
2164 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2165 }
2166 if(clear_parent_script_UID)
2167 {
2168 parent_script_UID = 0;
2169 }
2170 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2171 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2172
2173 for ( int32_t q = 0; q < 8; q++ )
2174 {
2175 initD[q] = other.initD[q];
2176 weap_initiald[q] = other.weap_initiald[q];
2177 }
2178 for ( int32_t q = 0; q < 2; q++ )
2179 {
2180 initA[q] = other.initA[q];
2181 weap_initiala[q] = other.weap_initiala[q];
2182 }
2183 }
2184
2185 esPatra::esPatra(esPatra const & other, bool new_script_uid, bool clear_parent_script_UID):
2186 //Struct Element Type Purpose
2187 //sprite(other),
2188 enemy(other)
2189
2190 {
2191
2192 //arrays
2193
2194 if(other.scrmem)
2195 {
2196 alloc_scriptmem();
2197 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2198
2199 scrmem->scriptData = other.scrmem->scriptData;
2200 }
2201 else scrmem = NULL;
2202 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2203 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2204
2205 for ( int32_t q = 0; q < 255; q++ )
2206 {
2207 nx[q] = other.nx[q];
2208 ny[q] = other.ny[q];
2209 nxoffset[q] = other.nxoffset[q];
2210 nyoffset[q] = other.nyoffset[q];
2211 }
2212
2213 for(int32_t i=0; i<edefLAST255; i++)
2214 defense[i]=other.defense[i];
2215 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2216 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2217
2218 if(new_script_uid)
2219 {
2220 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2221 }
2222 if(clear_parent_script_UID)
2223 {
2224 parent_script_UID = 0;
2225 }
2226 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2227 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2228
2229 for ( int32_t q = 0; q < 8; q++ )
2230 {
2231 initD[q] = other.initD[q];
2232 weap_initiald[q] = other.weap_initiald[q];
2233 }
2234 for ( int32_t q = 0; q < 2; q++ )
2235 {
2236 initA[q] = other.initA[q];
2237 weap_initiala[q] = other.weap_initiala[q];
2238 }
2239 }
2240
2241 esPatraBS::esPatraBS(esPatraBS const & other, bool new_script_uid, bool clear_parent_script_UID):
2242 //Struct Element Type Purpose
2243 //sprite(other),
2244 enemy(other)
2245
2246 {
2247
2248 //arrays
2249
2250 if(other.scrmem)
2251 {
2252 alloc_scriptmem();
2253 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2254
2255 scrmem->scriptData = other.scrmem->scriptData;
2256 }
2257 else scrmem = NULL;
2258 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2259 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2260
2261 for ( int32_t q = 0; q < 255; q++ )
2262 {
2263 nx[q] = other.nx[q];
2264 ny[q] = other.ny[q];
2265 nxoffset[q] = other.nxoffset[q];
2266 nyoffset[q] = other.nyoffset[q];
2267 }
2268
2269 for(int32_t i=0; i<edefLAST255; i++)
2270 defense[i]=other.defense[i];
2271 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2272 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2273
2274 if(new_script_uid)
2275 {
2276 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2277 }
2278 if(clear_parent_script_UID)
2279 {
2280 parent_script_UID = 0;
2281 }
2282 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2283 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2284
2285 for ( int32_t q = 0; q < 8; q++ )
2286 {
2287 initD[q] = other.initD[q];
2288 weap_initiald[q] = other.weap_initiald[q];
2289 }
2290 for ( int32_t q = 0; q < 2; q++ )
2291 {
2292 initA[q] = other.initA[q];
2293 weap_initiala[q] = other.weap_initiala[q];
2294 }
2295 }
2296
2297 */
2298
2299
5/10
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 398 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 398 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 398 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 398 times.
✗ Branch 9 not taken.
1194 enemy::enemy(zfix X,zfix Y,int32_t Id,int32_t Clk) : sprite()
2300 796 {
2301
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 x=X;
2302
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 y=Y;
2303 398 id=Id;
2304 398 clk=Clk;
2305
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 floor_y=y;
2306 398 ceiling=false;
2307 398 fading = misc = clk2 = clk3 = stunclk = hclk = sclk = superman = 0;
2308 398 grumble = movestatus = posframe = timer = ox = oy = 0;
2309
4/8
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 398 times.
✓ Branch 4 taken 398 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 398 times.
✗ Branch 7 not taken.
398 yofs = (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) - ((isSideViewGravity()) ? 0 : 2);
2310 398 did_armos=true;
2311 398 script_spawned=false;
2312
2313 398 d = guysbuf + (id & 0xFFF);
2314 398 hp = d->hp;
2315 398 starting_hp = hp;
2316 // cs = d->cset;
2317 //d variables
2318
2319 398 flags=d->flags;
2320 398 flags2=d->flags2;
2321 398 s_tile=d->s_tile; //secondary (additional) tile(s)
2322 398 family=d->family;
2323 398 dcset=d->cset;
2324 398 cs=dcset;
2325
3/4
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✓ Branch 3 taken 210 times.
398 anim=get_bit(quest_rules,qr_NEWENEMYTILES)?d->e_anim:d->anim;
2326 398 dp=d->dp;
2327 398 wdp=d->wdp;
2328 398 wpn=d->weapon;
2329 398 wpnsprite = d-> wpnsprite; //2.6 -Z
2330 398 rate=d->rate;
2331 398 hrate=d->hrate;
2332
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 dstep=d->step;
2333 398 homing=d->homing;
2334 398 dmisc1=d->misc1;
2335 398 dmisc2=d->misc2;
2336 398 dmisc3=d->misc3;
2337 398 dmisc4=d->misc4;
2338 398 dmisc5=d->misc5;
2339 398 dmisc6=d->misc6;
2340 398 dmisc7=d->misc7;
2341 398 dmisc8=d->misc8;
2342 398 dmisc9=d->misc9;
2343 398 dmisc10=d->misc10;
2344 398 dmisc11=d->misc11;
2345 398 dmisc12=d->misc12;
2346 398 dmisc13=d->misc13;
2347 398 dmisc14=d->misc14;
2348 398 dmisc15=d->misc15;
2349 398 dmisc16=d->misc16;
2350 398 dmisc17=d->misc17;
2351 398 dmisc18=d->misc18;
2352 398 dmisc19=d->misc19;
2353 398 dmisc20=d->misc20;
2354 398 dmisc21=d->misc21;
2355 398 dmisc22=d->misc22;
2356 398 dmisc23=d->misc23;
2357 398 dmisc24=d->misc24;
2358 398 dmisc25=d->misc25;
2359 398 dmisc26=d->misc26;
2360 398 dmisc27=d->misc27;
2361 398 dmisc28=d->misc28;
2362 398 dmisc29=d->misc29;
2363 398 dmisc30=d->misc30;
2364 398 dmisc31=d->misc31;
2365 398 dmisc32=d->misc32;
2366
3/4
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 388 times.
✓ Branch 3 taken 10 times.
398 if (get_bit(quest_rules, qr_BROKEN_ATTRIBUTE_31_32))
2367 {
2368 388 dmisc31 = dmisc32;
2369 388 dmisc32 = 0;
2370 388 }
2371 398 spr_shadow=d->spr_shadow;
2372 398 spr_death=d->spr_death;
2373 398 spr_spawn=d->spr_spawn;
2374
2375
2/2
✓ Branch 0 taken 16318 times.
✓ Branch 1 taken 398 times.
16716 for(int32_t i=0; i<edefLAST255; i++)
2376 16318 defense[i]=d->defense[i];
2377
2378 398 bgsfx=d->bgsfx;
2379 398 hitsfx=d->hitsfx;
2380 398 deadsfx=d->deadsfx;
2381 398 bosspal=d->bosspal;
2382 398 parent_script_UID = 0;
2383
2384 398 frozentile = d->frozentile;
2385
2386 398 frozencset = d->frozencset;
2387 398 frozenclock = 0;
2388
2/2
✓ Branch 0 taken 3980 times.
✓ Branch 1 taken 398 times.
4378 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = d->frozenmisc[q];
2389
2390
2/2
✓ Branch 0 taken 398 times.
✓ Branch 1 taken 6368 times.
6766 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = 0;
2391 //firesfx = 0; //t.b.a -Z
2392 398 isCore = true; //t.b.a
2393 398 parentCore = 0; //t.b.a
2394
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2395
2396 398 firesfx = d->firesfx;
2397
2/2
✓ Branch 0 taken 12736 times.
✓ Branch 1 taken 398 times.
13134 for ( int32_t q = 0; q < 32; q++ ) movement[q] = d->movement[q];
2398
2/2
✓ Branch 0 taken 12736 times.
✓ Branch 1 taken 398 times.
13134 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = d->new_weapon[q];
2399
2400
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 script = (d->script >= 0) ? d->script : 0; //Dont assign invalid data.
2401 398 waitdraw = 0;
2402
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 weaponscript = (d->weaponscript >= 0) ? d->weaponscript : 0; //Dont assign invalid data.
2403
2404
2/2
✓ Branch 0 taken 3184 times.
✓ Branch 1 taken 398 times.
3582 for ( int32_t q = 0; q < 8; q++ )
2405 {
2406 3184 initD[q] = d->initD[q];
2407 //Z_scripterrlog("(enemy::enemy(zfix)): Loading weapon InitD[%d] to an enemy with a value of (%d)\n",q,d->weap_initiald[q]);
2408 3184 weap_initiald[q] = d->weap_initiald[q];
2409 //al_trace("Guys.cpp: Assigning guy.initD[%d]: %d\n",q, d->initD.initD[q]);
2410 //al_trace("Guys.cpp: Assigning guy.initD[%d] from d->initD[%d]: %d\n",q,q, d->initD[q]);
2411 //al_trace("Guys.cpp: guy.initD[%d] is: %d\n",q, initD[q]);
2412 3184 }
2413
2/2
✓ Branch 0 taken 796 times.
✓ Branch 1 taken 398 times.
1194 for ( int32_t q = 0; q < 2; q++ )
2414 {
2415 796 initA[q] = d->initA[q];
2416 796 weap_initiala[q] = d->weap_initiala[q];
2417 796 }
2418
2419 398 stickclk = 0;
2420 398 submerged = false;
2421 398 ffcactivated = 0;
2422 398 hitdir = -1;
2423 398 dialogue_str = 0; //set by spawn flags.
2424 398 editorflags = d->editorflags; //set by Enemy Editor
2425 //Set the drawing flag for this sprite.
2426
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 if ( (editorflags&ENEMY_FLAG12) ) { drawflags |= sprdrawflagALWAYSOLDDRAWS; }
2427
2428
2429
2/2
✓ Branch 0 taken 161 times.
✓ Branch 1 taken 237 times.
398 if(bosspal>-1)
2430 {
2431
1/2
✓ Branch 0 taken 161 times.
✗ Branch 1 not taken.
161 loadpalset(csBOSS,pSprite(bosspal));
2432 161 }
2433
2434
2/2
✓ Branch 0 taken 206 times.
✓ Branch 1 taken 192 times.
398 if(bgsfx>-1)
2435 {
2436
1/2
✓ Branch 0 taken 206 times.
✗ Branch 1 not taken.
206 cont_sfx(bgsfx);
2437 206 }
2438
2439
3/4
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 188 times.
✓ Branch 3 taken 210 times.
398 if(get_bit(quest_rules,qr_NEWENEMYTILES))
2440 {
2441 188 o_tile=d->e_tile;
2442 188 frate = d->e_frate;
2443 188 }
2444 else
2445 {
2446 210 o_tile=d->tile;
2447 210 frate = d->frate;
2448 }
2449
2450 398 tile=0; //init to 0 here, but set it later.
2451
2452 398 scripttile = -1;
2453 398 scriptflip = -1;
2454 398 do_animation = 1;
2455 398 immortal = false;
2456 398 noSlide = false;
2457 398 deathexstate = -1;
2458
2459 398 hashero=false;
2460
2461 // If they forgot the invisibility flag, here's another failsafe:
2462
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 389 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
398 if(o_tile==0 && family!=eeSPINTILE)
2463 9 flags |= guy_invisible;
2464
2465 // step = d->step/100.0;
2466 // To preserve the odd step values for Keese & Gleeok heads. -L
2467
5/8
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 398 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88 times.
✓ Branch 5 taken 310 times.
✓ Branch 6 taken 88 times.
✗ Branch 7 not taken.
398 if(dstep==62.0) dstep+=0.5;
2468
3/8
✓ Branch 0 taken 310 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 310 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 310 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
310 else if(dstep==89) dstep-=1/9;
2469
2470
5/10
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 398 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 398 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 398 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 398 times.
✗ Branch 9 not taken.
398 step = zslongToFix(dstep*100);
2471
2472
2473 398 item_set = d->item_set;
2474 398 grumble = d->grumble;
2475
2476
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 109 times.
398 if(frate == 0)
2477 109 frate = 256;
2478
2479 398 leader = itemguy = dying = scored = false;
2480 398 canfreeze = count_enemy = true;
2481 398 mainguy = !(flags & guy_doesntcount);
2482
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 dir = zc_oldrand()&3;
2483
2484 //2.6 Enemy Editor Hit and TIle Sizes
2485
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 398 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
398 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
2486 //al_trace("->txsz:%i\n", d->txsz); Verified that this is setting the value. -Z
2487 // al_trace("Enemy txsz:%i\n", txsz);
2488
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 398 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
398 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
2489
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 398 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
398 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
2490
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 398 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
398 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
2491
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 398 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
398 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
2492
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
2493
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
2494 // if ( (d->SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = d->hzofs;
2495
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 398 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
398 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
2496
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 398 times.
398 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
2497 {
2498 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
2499 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
2500 }
2501
2502
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 398 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
398 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
2503
2504 398 SIZEflags = d->SIZEflags;
2505
2506
2/10
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 398 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
398 if((wpn==ewBomb || wpn==ewSBomb) && family!=eeOTHER && family!=eeFIRE && (family!=eeWALK || dmisc2 != e2tBOMBCHU))
2507 wpn = 0;
2508
2509 //tile should never be 0 after init --Z (failsafe)
2510
4/6
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 398 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 388 times.
✓ Branch 5 taken 10 times.
398 if (tile <= 0 && FFCore.getQuestHeaderInfo(vZelda) >= 0x255) {tile = o_tile;}
2511
2512 //Moveflags; for gravity and pit interaction
2513 398 moveflags = d->moveflags;
2514
3/4
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 354 times.
✓ Branch 3 taken 44 times.
398 if(!can_pitfall(false))
2515 {
2516 //Some enemies must not interact with pits. Force their flags, for sanity's sake.
2517 44 moveflags &= ~FLAG_CAN_PITFALL;
2518 44 moveflags &= ~FLAG_CAN_WATERDROWN;
2519 44 }
2520
2521
1/2
✓ Branch 0 taken 398 times.
✗ Branch 1 not taken.
398 shieldCanBlock = get_bit(quest_rules,qr_GOHMA_UNDAMAGED_BUG)?true:false;
2522 398 }
2523
2524 //base clone constructor
2525
2526 enemy::enemy(enemy const & other, bool new_script_uid, bool clear_parent_script_UID):
2527 //Struct Element Type Purpose
2528 sprite(other),
2529 //x(other.x), //int32_t
2530 //y(other.y), //int32_t
2531 //id(other.id), //int32_t
2532 //clk(other.clk), //int32_t
2533 floor_y(other.floor_y), //int32_t
2534 fading(other.fading), //int32_t
2535 //misc(other.misc), //int32_t
2536 clk2(other.clk2), //int32_t
2537 clk3(other.clk3), //int32_t
2538 stunclk(other.stunclk), //int32_t
2539 hclk(other.hclk), //int32_t
2540 sclk(other.sclk), //int32_t
2541 superman(other.superman), //int32_t
2542 //grumble(other.grumble), //int32_t
2543 movestatus(other.movestatus), //int32_t
2544 posframe(other.posframe), //int32_t
2545 timer(other.timer), //int32_t
2546 ox(other.ox), //int32_t
2547 oy(other.oy), //int32_t
2548 //yofs(other.yofs), //int32_t
2549 did_armos(other.did_armos), //int32_t
2550 script_spawned(other.script_spawned), //int32_t
2551 d(other.d), //int32_t
2552 hp(other.hp), //int32_t
2553 starting_hp(other.starting_hp), //int32_t
2554 //flags(other.flags), //int32_t
2555
2556 flags2(other.flags2), //int32_t
2557 s_tile(other.s_tile), //int32_t
2558 family(other.family), //int32_t
2559 dcset(other.dcset), //int32_t
2560 //cs(other.cs), //int32_t
2561 anim(other.anim), //int32_t
2562 dp(other.dp), //int32_t
2563 wdp(other.wdp), //int32_t
2564 wpnsprite(other.wpnsprite), //int32_t
2565 rate(other.rate), //int32_t
2566 hrate(other.hrate), //int32_t
2567 dstep(other.dstep), //int32_t
2568
2569 homing(other.homing), //int32_t
2570 dmisc1(other.dmisc1), //int32_t
2571 dmisc2(other.dmisc2), //int32_t
2572 dmisc3(other.dmisc3), //int32_t
2573 dmisc4(other.dmisc4), //int32_t
2574 dmisc5(other.dmisc5), //int32_t
2575 dmisc6(other.dmisc6), //int32_t
2576 dmisc7(other.dmisc7), //int32_t
2577 dmisc8(other.dmisc8), //int32_t
2578 dmisc9(other.dmisc9), //int32_t
2579 dmisc10(other.dmisc10), //int32_t
2580 dmisc11(other.dmisc11), //int32_t
2581 dmisc12(other.dmisc12), //int32_t
2582 dmisc13(other.dmisc13), //int32_t
2583 dmisc14(other.dmisc14), //int32_t
2584 dmisc15(other.dmisc15), //int32_t
2585 dmisc16(other.dmisc16), //int32_t
2586 dmisc17(other.dmisc17), //int32_t
2587 dmisc18(other.dmisc18), //int32_t
2588 dmisc19(other.dmisc19), //int32_t
2589 dmisc20(other.dmisc20), //int32_t
2590 dmisc21(other.dmisc21), //int32_t
2591 dmisc22(other.dmisc22), //int32_t
2592 dmisc23(other.dmisc23), //int32_t
2593 dmisc24(other.dmisc24), //int32_t
2594 dmisc25(other.dmisc25), //int32_t
2595 dmisc26(other.dmisc26), //int32_t
2596 dmisc27(other.dmisc27), //int32_t
2597 dmisc28(other.dmisc28), //int32_t
2598 dmisc29(other.dmisc29), //int32_t
2599 dmisc30(other.dmisc30), //int32_t
2600 dmisc31(other.dmisc31), //int32_t
2601 dmisc32(other.dmisc32), //int32_t
2602 bgsfx(other.bgsfx), //int32_t
2603 hitsfx(other.hitsfx), //int32_t
2604 deadsfx(other.deadsfx), //int32_t
2605 bosspal(other.bosspal), //int32_t
2606 parent_script_UID(other.parent_script_UID), //int32_t
2607 frozentile(other.frozentile), //int32_t
2608 frozencset(other.frozencset), //int32_t
2609 frozenclock(other.frozenclock), //int32_t
2610 isCore(other.isCore), //int32_t
2611 parentCore(other.parentCore), //int32_t
2612 script_UID(other.script_UID), //int32_t
2613 firesfx(other.firesfx), //int32_t
2614 //script(other.script), //int32_t
2615 //waitdraw(other.waitdraw), //int32_t
2616 weaponscript(other.weaponscript), //int32_t
2617 stickclk(other.stickclk), //int32_t
2618 hitdir(other.hitdir), //int32_t
2619 submerged(other.submerged), //int32_t
2620 ffcactivated(other.ffcactivated), //word
2621
2622 dialogue_str(other.dialogue_str), //int32_t
2623 editorflags(other.editorflags), //int32_t
2624 //drawflags(other.drawflags), //int32_t
2625 o_tile(other.o_tile), //int32_t
2626 frate(other.frate), //int32_t
2627 //tile(other.tile), //int32_t
2628 //scripttile(other.scripttile), //int32_t
2629 //scriptflip(other.scriptflip), //int32_t
2630 //do_animation(other.do_animation), //int32_t
2631 immortal(other.immortal), //bool
2632 noSlide(other.noSlide), //bool
2633 deathexstate(other.deathexstate), //int32_t
2634 flags(other.flags), //int32_t
2635 step(other.step), //int32_t
2636
2637 item_set(other.item_set), //int32_t
2638 grumble(other.grumble), //int32_t
2639 leader(other.leader), //int32_t
2640 itemguy(other.itemguy), //int32_t
2641 dying(other.dying), //int32_t
2642 scored(other.scored), //int32_t
2643 //canfreeze(other.canfreeze), //int32_t
2644 count_enemy(other.count_enemy), //int32_t
2645 mainguy(other.mainguy), //int32_t
2646 //dir(other.dir), //int32_t
2647
2648 //txsz(other.txsz), //int32_t
2649 //tysz(other.tysz), //int32_t
2650 //hxsz(other.hxsz), //int32_t
2651 //hysz(other.hysz), //int32_t
2652 //hzsz(other.hzsz), //int32_t
2653 //hxofs(other.hxofs), //int32_t
2654 //hxofs(other.hxofs), //int32_t
2655 //xofs(other.xofs), //int32_t
2656 //yofs(other.yofs), //int32_t
2657 //hzofs(other.hzofs), //int32_t
2658 //zofs(other.zofs), //int32_t
2659
2660 wpn(other.wpn), //int32_t
2661 SIZEflags(other.SIZEflags), //int32_t
2662 hashero(other.hashero)
2663
2664 {
2665
2666 //arrays
2667
2668 if(other.scrmem)
2669 {
2670 alloc_scriptmem();
2671 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2672
2673 scrmem->scriptData = other.scrmem->scriptData;
2674 }
2675 else scrmem = NULL;
2676 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2677 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2678
2679 for(int32_t i=0; i<edefLAST255; i++)
2680 defense[i]=other.defense[i];
2681 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2682 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2683
2684 if(new_script_uid)
2685 {
2686 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2687 }
2688 if(clear_parent_script_UID)
2689 {
2690 parent_script_UID = 0;
2691 }
2692 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2693 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2694
2695 for ( int32_t q = 0; q < 8; q++ )
2696 {
2697 initD[q] = other.initD[q];
2698 weap_initiald[q] = other.weap_initiald[q];
2699 }
2700 for ( int32_t q = 0; q < 2; q++ )
2701 {
2702 initA[q] = other.initA[q];
2703 weap_initiala[q] = other.weap_initiala[q];
2704 }
2705 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
2706 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
2707 // al_trace("Enemy txsz:%i\n", txsz);
2708 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = tysz; if ( tysz > 1 ) extend = 3; }
2709 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = hxsz;
2710 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = hysz;
2711 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = hzsz;
2712 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = hxofs;
2713 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = hyofs;
2714 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
2715 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)xofs;
2716 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
2717 {
2718 yofs = (int32_t)yofs; //This seems to be setting to +48 or something with any value set?! -Z
2719 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
2720 }
2721
2722 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
2723
2724
2725
2726
2727 }
2728
2729
2730 int32_t enemy::getScriptUID() { return script_UID; }
2731 void enemy::setScriptUID(int32_t new_id) { script_UID = new_id; }
2732 395 enemy::~enemy()
2733 395 {
2734
2/4
✓ Branch 0 taken 395 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 395 times.
✗ Branch 3 not taken.
395 FFCore.deallocateAllArrays(SCRIPT_NPC, getUID());
2735 395 }
2736
2737
2738 bool enemy::is_move_paused()
2739 {
2740 return (clk<0 || dying || stunclk || watch || ceiling || frozenclock || fallclk || drownclk);
2741 }
2742
2743 bool enemy::scr_walkflag(int32_t dx,int32_t dy,int32_t special, int32_t dir, int32_t input_x, int32_t input_y, bool kb)
2744 {
2745 int32_t yg = (special==spw_floater)?8:0;
2746 int32_t nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
2747 //Z_eventlog("Checking x,y %d,%d\n",dx,dy);
2748 if(input_x == -1000)
2749 input_x = dx;
2750 if(input_y == -1000)
2751 input_y = dy;
2752
2753 if(!(moveflags & FLAG_IGNORE_SCREENEDGE)
2754 && (input_x<16-nb || input_y<zc_max(16-yg-nb,0)
2755 || input_x>=240+nb-hxsz || input_y>=160+nb-hysz))
2756 return true;
2757
2758 if(!(moveflags & FLAG_CAN_PITWALK) && (!(moveflags & FLAG_CAN_PITFALL) || !kb)) //Don't walk into pits, unless being knocked back
2759 {
2760 if(ispitfall(dx,dy))
2761 return true;
2762 }
2763
2764 bool flying = false;
2765 bool cansolid = false;
2766 if(moveflags & FLAG_IGNORE_SOLIDITY)
2767 cansolid = true;
2768 switch(special)
2769 {
2770 case spw_clipbottomright:
2771 if(dy>=128 || dx>=208) return true;
2772 break;
2773 case spw_clipright:
2774 break; //if(input_x>=208) return true; break;
2775
2776 case spw_wizzrobe: // fall through
2777 case spw_floater: // Special case for fliers and wizzrobes - hack!
2778 {
2779 if(isdungeon() && !(moveflags & FLAG_IGNORE_SCREENEDGE))
2780 {
2781 if(dy < 32-yg || dy >= 144) return true;
2782 if(dx < 32 || dx >= 224) return true;
2783 }
2784 if(!(moveflags & FLAG_IGNORE_BLOCKFLAGS) && flyerblocked(dx, dy, special, kb))
2785 return true;
2786 cansolid = true;
2787 flying = true;
2788 }
2789 }
2790
2791 dx &= ~7;
2792 dy &= ~7;
2793
2794 if(!flying && !(moveflags & FLAG_IGNORE_BLOCKFLAGS) && groundblocked(dx,dy,kb)) return true;
2795
2796 if (dx < 0 || dx > 255 || dy < 0 || dy > 175)
2797 return false;
2798 //_walkflag code
2799 mapscr *s1, *s2;
2800 s1=(((*tmpscr).layermap[0]-1)>=0)?tmpscr2:NULL;
2801 s2=(((*tmpscr).layermap[1]-1)>=0)?tmpscr2+1:NULL;
2802
2803 int32_t cpos=(dx>>4)+(dy&0xF0);
2804 int32_t ci = tmpscr->data[cpos], ci1 = (s1?s1:tmpscr)->data[cpos], ci2 = (s2?s2:tmpscr)->data[cpos];
2805 newcombo const& c = combobuf[ci];
2806 newcombo const& c1 = combobuf[ci1];
2807 newcombo const& c2 = combobuf[ci2];
2808
2809 int32_t b=1;
2810 if(dx&8) b<<=2;
2811 if(dy&8) b<<=1;
2812
2813 #define iwtr(cmb, x, y, shallow) \
2814 (shallow \
2815 ? iswaterex(cmb, currmap, currscr, -1, dx, dy, false, false, false, true, false) \
2816 && !iswaterex(cmb, currmap, currscr, -1, dx, dy, false, false, false, false, false) \
2817 : iswaterex(cmb, currmap, currscr, -1, dx, dy, false, false, false, false, false))
2818 bool wtr = iwtr(ci, dx, dy, false);
2819 bool shwtr = iwtr(ci, dx, dy, true);
2820 bool pit = ispitfall(dx,dy);
2821
2822 bool canwtr = (moveflags & FLAG_CAN_WATERWALK) || ((moveflags & FLAG_CAN_WATERDROWN) && kb);
2823 bool canpit = (moveflags & FLAG_CAN_PITWALK) || ((moveflags & FLAG_CAN_PITFALL) && kb);
2824 bool needwtr = (moveflags & FLAG_ONLY_WATERWALK);
2825 bool needshwtr = (moveflags & FLAG_ONLY_SHALLOW_WATERWALK);
2826 bool needpit = (moveflags & FLAG_ONLY_PITWALK);
2827
2828 int32_t cwalkflag = c.walk & 0xF;
2829 if (c.type == cBRIDGE && get_bit(quest_rules, qr_OLD_BRIDGE_COMBOS)) cwalkflag = 0;
2830 if (s1)
2831 {
2832 if (c1.type == cBRIDGE)
2833 {
2834 if (!get_bit(quest_rules, qr_OLD_BRIDGE_COMBOS))
2835 {
2836 int efflag = (c1.walk & 0xF0)>>4;
2837 int newsolid = (c1.walk & 0xF);
2838 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
2839 }
2840 else cwalkflag &= c1.walk;
2841 }
2842 else cwalkflag |= c1.walk & 0xF;
2843 }
2844 if (s2)
2845 {
2846 if (c2.type == cBRIDGE)
2847 {
2848 if (!get_bit(quest_rules, qr_OLD_BRIDGE_COMBOS))
2849 {
2850 int efflag = (c2.walk & 0xF0)>>4;
2851 int newsolid = (c2.walk & 0xF);
2852 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
2853 }
2854 else cwalkflag &= c2.walk;
2855 }
2856 else cwalkflag |= c2.walk & 0xF;
2857 }
2858 bool solid = cwalkflag & b;
2859 if (solid && !cansolid) return true;
2860 if(needwtr || needshwtr || needpit)
2861 {
2862 bool ret = true;
2863 if (needwtr && wtr) ret = false;
2864 else if (needshwtr && shwtr) ret = false;
2865 else if (needpit && pit) ret = false;
2866 return ret;
2867 }
2868 else if(wtr && !canwtr)
2869 return true;
2870 else if(pit && !canpit)
2871 return true;
2872
2873 return false;
2874 }
2875
2876 bool enemy::scr_canmove(zfix dx, zfix dy, int32_t special, bool kb, bool ign_sv)
2877 {
2878 if(!(dx || dy)) return true;
2879 zfix bx = x+hxofs, by = y+hyofs; //left/top
2880 zfix rx = bx+hxsz-1, ry = by+hysz-1; //right/bottom
2881 if(!ign_sv && dy < 0) //check gravity
2882 {
2883 if((moveflags & FLAG_OBEYS_GRAV) && isSideViewGravity())
2884 return false;
2885 }
2886
2887 if(dx && !dy)
2888 {
2889 if(dx < 0)
2890 {
2891 special = (special==spw_clipbottomright||special==spw_clipright)?spw_none:special;
2892 int32_t tx = (bx+dx).getFloor();
2893 for(zfix ty = 0; by+ty < ry; ty += 8)
2894 {
2895 if(scr_walkflag(tx, by+ty, special, left, bx, by, kb))
2896 return false;
2897 }
2898 if(scr_walkflag(tx, ry, special, left, bx, by, kb))
2899 return false;
2900 }
2901 else
2902 {
2903 int32_t tx = (rx+dx).getCeil();
2904 for(zfix ty = 0; by+ty < ry; ty += 8)
2905 {
2906 if(scr_walkflag(tx, by+ty, special, right, bx, by, kb))
2907 return false;
2908 }
2909 if(scr_walkflag(tx, ry, special, right, bx, by, kb))
2910 return false;
2911 }
2912 }
2913 else if(dy && !dx)
2914 {
2915 if(dy < 0)
2916 {
2917 special = (special==spw_clipbottomright)?spw_none:special;
2918 int32_t ty = (by+dy).getFloor();
2919 for(zfix tx = 0; bx+tx < rx; tx += 8)
2920 {
2921 if(scr_walkflag(bx+tx, ty, special, up, bx, by, kb))
2922 return false;
2923 }
2924 if(scr_walkflag(rx, ty, special, up, bx, by, kb))
2925 return false;
2926 }
2927 else
2928 {
2929 int32_t ty = (ry+dy).getCeil();
2930 for(zfix tx = 0; bx+tx < rx; tx += 8)
2931 {
2932 if(scr_walkflag(bx+tx, ty, special, down, bx, by, kb))
2933 return false;
2934 }
2935 if(scr_walkflag(rx, ty, special, down, bx, by, kb))
2936 return false;
2937 }
2938 }
2939 else
2940 {
2941 return scr_canmove(dx, 0, special, kb, ign_sv) && scr_canmove(dy, 0, special, kb, ign_sv);
2942 }
2943 return true;
2944 }
2945
2946 bool enemy::scr_canplace(zfix dx, zfix dy, int32_t special, bool kb)
2947 {
2948 zfix bx = dx+hxofs, by = dy+hyofs; //left/top
2949 zfix rx = bx+hxsz-1, ry = by+hysz-1; //right/bottom
2950
2951 for(zfix ty = 0; by+ty < ry; ty += 8)
2952 {
2953 for(zfix tx = 0; bx+tx < rx; tx += 8)
2954 {
2955 if(scr_walkflag(bx+tx, by+ty, special, -1, -1000, -1000, kb))
2956 return false;
2957 }
2958 if(scr_walkflag(rx, by+ty, special, -1, -1000, -1000, kb))
2959 return false;
2960 }
2961 for(zfix tx = 0; bx+tx < rx; tx += 8)
2962 {
2963 if(scr_walkflag(bx+tx, ry, special, -1, -1000, -1000, kb))
2964 return false;
2965 }
2966 if(scr_walkflag(rx, ry, special, -1, -1000, -1000, kb))
2967 return false;
2968 return true;
2969 }
2970
2971 bool enemy::movexy(zfix dx, zfix dy, int32_t special, bool kb, bool ign_sv)
2972 {
2973 bool ret = true;
2974 if(!ign_sv && dy < 0 && (moveflags & FLAG_OBEYS_GRAV) && isSideViewGravity())
2975 dy = 0;
2976 while(abs(dx) > 8 || abs(dy) > 8)
2977 {
2978 if(abs(dx) > abs(dy))
2979 {
2980 int32_t tdx = dx.sign() * 8;
2981 if(movexy(tdx, 0, special, kb, ign_sv))
2982 dx -= tdx;
2983 else
2984 {
2985 dx = tdx;
2986 ret = false;
2987 }
2988 }
2989 else
2990 {
2991 int32_t tdy = dy.sign() * 8;
2992 if(movexy(0, tdy, special, kb, ign_sv))
2993 dy -= tdy;
2994 else
2995 {
2996 dy = tdy;
2997 ret = false;
2998 }
2999 }
3000 }
3001 if(dx)
3002 {
3003 if(scr_canmove(dx, 0, special, kb, ign_sv))
3004 x += dx;
3005 else
3006 {
3007 ret = false;
3008 int32_t xsign = dx.sign();
3009 while(scr_canmove(xsign, 0, special, kb, ign_sv))
3010 {
3011 x += xsign;
3012 dx -= xsign;
3013 }
3014 if(scr_canmove(dx.decsign(), 0, special, kb, ign_sv)) //can move 0.0001 to 0.9999 px in this direction
3015 {
3016 if(dx > 0)
3017 x.doCeil();
3018 else x.doFloor();
3019 }
3020 }
3021 }
3022 if(dy)
3023 {
3024 if(scr_canmove(0, dy, special, kb, ign_sv))
3025 y += dy;
3026 else
3027 {
3028 ret = false;
3029 int32_t ysign = dy.sign();
3030 while(scr_canmove(0, ysign, special, kb, ign_sv))
3031 {
3032 y += ysign;
3033 dy -= ysign;
3034 }
3035 if(scr_canmove(0, dy.decsign(), special, kb, ign_sv)) //can move 0.0001 to 0.9999 px in this direction
3036 {
3037 if(dy > 0)
3038 y.doCeil();
3039 else y.doFloor();
3040 }
3041 }
3042 }
3043 return ret;
3044 }
3045
3046 bool enemy::moveDir(int32_t dir, zfix px, int32_t special, bool kb)
3047 {
3048 zfix diagrate = zslongToFix(7071);
3049 switch(NORMAL_DIR(dir))
3050 {
3051 case up:
3052 return movexy(0, -px, special, kb);
3053 case down:
3054 return movexy(0, px, special, kb);
3055 case left:
3056 return movexy(-px, 0, special, kb);
3057 case right:
3058 return movexy(px, 0, special, kb);
3059 case r_up:
3060 return movexy(px*diagrate, -px*diagrate, special, kb);
3061 case r_down:
3062 return movexy(px*diagrate, px*diagrate, special, kb);
3063 case l_up:
3064 return movexy(-px*diagrate, -px*diagrate, special, kb);
3065 case l_down:
3066 return movexy(-px*diagrate, px*diagrate, special, kb);
3067 }
3068 return false;
3069 }
3070
3071 bool enemy::moveAtAngle(zfix degrees, zfix px, int32_t special, bool kb)
3072 {
3073 double v = degrees.getFloat() * PI / 180.0;
3074 zfix dx = zc::math::Cos(v)*px, dy = zc::math::Sin(v)*px;
3075 return movexy(dx, dy, special, kb);
3076 }
3077
3078 bool enemy::can_movexy(zfix dx, zfix dy, int32_t special, bool kb)
3079 {
3080 zfix tx = x, ty = y;
3081 bool ret = movexy(dx, dy, special, kb);
3082 x = tx;
3083 y = ty;
3084 return ret;
3085 }
3086 bool enemy::can_moveDir(int32_t dir, zfix px, int32_t special, bool kb)
3087 {
3088 zfix tx = x, ty = y;
3089 bool ret = moveDir(dir, px, special, kb);
3090 x = tx;
3091 y = ty;
3092 return ret;
3093 }
3094 bool enemy::can_moveAtAngle(zfix degrees, zfix px, int32_t special, bool kb)
3095 {
3096 zfix tx = x, ty = y;
3097 bool ret = moveAtAngle(degrees, px, special, kb);
3098 x = tx;
3099 y = ty;
3100 return ret;
3101 }
3102
3103 // Handle pitfalls
3104 138890 bool enemy::do_falling(int32_t index)
3105 {
3106
1/2
✓ Branch 0 taken 138890 times.
✗ Branch 1 not taken.
138890 if(fallclk > 0)
3107 {
3108 if(fallclk == PITFALL_FALL_FRAMES && fallCombo) sfx(combobuf[fallCombo].attribytes[0], pan(x.getInt()));
3109 if(!--fallclk)
3110 {
3111 if(immortal) //Keep alive forever
3112 ++fallclk; //force another frame of falling.... forever.
3113 else if(dying) //Give 1 frame for script revival
3114 {
3115 if(flags&guy_neverret)
3116 never_return(index);
3117
3118 if(leader)
3119 kill_em_all();
3120
3121 //leave_item(); //Don't drop items in pits!
3122 stop_bgsfx(index);
3123 return true;
3124 }
3125 else
3126 {
3127 try_death(true); //Force death
3128 ++fallclk; //force another frame of falling
3129 }
3130 }
3131
3132 wpndata& spr = wpnsbuf[QMisc.sprites[sprFALL]];
3133 cs = spr.csets & 0xF;
3134 int32_t fr = spr.frames ? spr.frames : 1;
3135 int32_t spd = spr.speed ? spr.speed : 1;
3136 int32_t animclk = (PITFALL_FALL_FRAMES-fallclk);
3137 tile = spr.tile + zc_min(animclk / spd, fr-1);
3138 }
3139 138890 return false;
3140 138890 }
3141
3142 // Handle drowning in water
3143 138890 bool enemy::do_drowning(int32_t index)
3144 {
3145
1/2
✓ Branch 0 taken 138890 times.
✗ Branch 1 not taken.
138890 if(drownclk > 0)
3146 {
3147 //if(drownclk == WATER_DROWN_FRAMES && drownCombo) sfx(combobuf[drownCombo].attribytes[0], pan(x.getInt()));
3148 //!TODO: Drown SFX
3149 if(!--drownclk)
3150 {
3151 if(immortal) //Keep alive forever
3152 ++drownclk; //force another frame of falling.... forever.
3153 else if(dying) //Give 1 frame for script revival
3154 {
3155 if(flags&guy_neverret)
3156 never_return(index);
3157
3158 if(leader)
3159 kill_em_all();
3160
3161 //leave_item(); //Don't drop items in pits!
3162 stop_bgsfx(index);
3163 return true;
3164 }
3165 else
3166 {
3167 try_death(true); //Force death
3168 ++drownclk; //force another frame of falling
3169 }
3170 }
3171
3172 if (drownCombo && combobuf[drownCombo].usrflags&cflag1)
3173 {
3174 wpndata &spr = wpnsbuf[QMisc.sprites[sprLAVADROWN]];
3175 cs = spr.csets & 0xF;
3176 int32_t fr = spr.frames ? spr.frames : 1;
3177 int32_t spd = spr.speed ? spr.speed : 1;
3178 int32_t animclk = (WATER_DROWN_FRAMES-drownclk);
3179 tile = spr.tile + zc_min((animclk % (spd*fr))/spd, fr-1);
3180 }
3181 else
3182 {
3183 wpndata &spr = wpnsbuf[QMisc.sprites[sprDROWN]];
3184 cs = spr.csets & 0xF;
3185 int32_t fr = spr.frames ? spr.frames : 1;
3186 int32_t spd = spr.speed ? spr.speed : 1;
3187 int32_t animclk = (WATER_DROWN_FRAMES-drownclk);
3188 tile = spr.tile + zc_min((animclk % (spd*fr))/spd, fr-1);
3189 }
3190 }
3191 138890 return false;
3192 138890 }
3193
3194 // Supplemental animation code that all derived classes should call
3195 // as a return value for animate().
3196 // Handles the death animation and returns true when enemy is finished.
3197 143341 bool enemy::Dead(int32_t index)
3198 {
3199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143341 times.
143341 if(immortal)
3200 {
3201 dying = false;
3202 return false;
3203 }
3204
2/2
✓ Branch 0 taken 4699 times.
✓ Branch 1 taken 138642 times.
143341 if(dying)
3205 {
3206
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4699 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4699 if(deathexstate > -1 && deathexstate < 32)
3207 {
3208 setxmapflag(1<<deathexstate);
3209 deathexstate = -1;
3210 }
3211 4699 --clk2;
3212
3213
2/4
✓ Branch 0 taken 4699 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 247 times.
✗ Branch 3 not taken.
4699 if((get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS) && clk2==12)
3214
2/2
✓ Branch 0 taken 247 times.
✓ Branch 1 taken 4452 times.
4699 && hp>-1000) // not killed by ringleader
3215 247 death_sfx();
3216
3217
2/2
✓ Branch 0 taken 4452 times.
✓ Branch 1 taken 247 times.
4699 if(clk2==0)
3218 {
3219
2/2
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 2 times.
247 if(flags&guy_neverret)
3220 2 never_return(index);
3221
3222
1/2
✓ Branch 0 taken 247 times.
✗ Branch 1 not taken.
247 if(leader)
3223 kill_em_all();
3224
3225 247 leave_item();
3226 247 }
3227
3228 4699 stop_bgsfx(index);
3229 4699 return (clk2==0);
3230 }
3231
3232 138642 return false;
3233 143341 }
3234
3235 // Basic animation code that all derived classes should call.
3236 // The one with an index is the one that is called by
3237 // the guys sprite list; index is the enemy's index in the list.
3238 140730 bool enemy::animate(int32_t index)
3239 {
3240
2/2
✓ Branch 0 taken 3484 times.
✓ Branch 1 taken 137246 times.
140730 if(sclk <= 0) hitdir = -1;
3241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 133762 times.
140730 if(switch_hooked)
3242 {
3243 if(get_bit(quest_rules, qr_SWITCHOBJ_RUN_SCRIPT))
3244 {
3245 //Run its script
3246 if (run_script(MODE_NORMAL)==RUNSCRIPT_SELFDELETE)
3247 {
3248 return 0; //Avoid NULLPO if this object deleted itself
3249 }
3250 }
3251 return false;
3252 }
3253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 133762 times.
133762 if(do_falling(index)) return true;
3254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 133762 times.
133762 else if(fallclk)
3255 {
3256 //clks
3257 if(hclk>0)
3258 --hclk;
3259 if(stunclk>0)
3260 --stunclk;
3261 if ( frozenclock > 0 )
3262 --frozenclock;
3263 if(hashero)
3264 {
3265 Hero.setX(x);
3266 Hero.setY(y);
3267 Hero.fallCombo = fallCombo;
3268 Hero.fallclk = fallclk;
3269 hashero = false; //Let Hero go if falling
3270 }
3271 run_script(MODE_NORMAL);
3272 return false;
3273 }
3274
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 133762 times.
133762 if(do_drowning(index)) return true;
3275
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 133762 times.
133762 else if(drownclk)
3276 {
3277 //clks
3278 if(hclk>0)
3279 --hclk;
3280 if(stunclk>0)
3281 --stunclk;
3282 if ( frozenclock > 0 )
3283 --frozenclock;
3284 if(hashero)
3285 {
3286 Hero.setX(x);
3287 Hero.setY(y);
3288 Hero.drownclk = drownclk;
3289 hashero = false; //Let Hero go if falling
3290 }
3291 run_script(MODE_NORMAL);
3292 return false;
3293 }
3294 133762 int32_t nx = real_x(x);
3295 133762 int32_t ny = real_y(y);
3296
3297
4/4
✓ Branch 0 taken 107715 times.
✓ Branch 1 taken 26047 times.
✓ Branch 2 taken 24780 times.
✓ Branch 3 taken 132495 times.
133762 if(ox!=nx || oy!=ny)
3298 {
3299 50827 posframe=(posframe+1)%(get_bit(quest_rules,qr_NEWENEMYTILES)?4:2);
3300 50827 }
3301
3302 183322 ox = nx;
3303 183322 oy = ny;
3304
3305 // Maybe they fell off the bottom in sideview, or were moved by a script.
3306
3307 //Check offscreen settings. I wrote it this way for clarity and to simplify testing. -Z
3308
2/2
✓ Branch 0 taken 44432 times.
✓ Branch 1 taken 138890 times.
183322 if ( immortal )
3309 {
3310 //skip, as it can go out of bounds, from immortality
3311 44432 }
3312
2/6
✓ Branch 0 taken 138890 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 138890 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
138890 else if ( (moveflags & FLAG_IGNORE_SCREENEDGE) || (( (get_bit(quest_rules, qr_OUTOFBOUNDSENEMIES)) != (editorflags&ENEMY_FLAG11) ) && !NEWOUTOFBOUNDS(x,y,z+fakez)) )
3313 {
3314 //skip, it can go out of bounds, from a quest rule, or from the enemy editor (but not both!)
3315 }
3316
5/10
✓ Branch 0 taken 138890 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 138890 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 138890 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 138890 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 138890 times.
138890 else if ( (OUTOFBOUNDS) )
3317 {
3318 hp=-1000; //kill it, as it is not immortal, and no quest bit or rule is enabled
3319 }
3320 //fall down
3321
6/6
✓ Branch 0 taken 50607 times.
✓ Branch 1 taken 132715 times.
✓ Branch 2 taken 88283 times.
✓ Branch 3 taken 95039 times.
✓ Branch 4 taken 5201 times.
✓ Branch 5 taken 83082 times.
183322 if((enemycanfall(id) || (moveflags & FLAG_OBEYS_GRAV) )&& fading != fade_flicker && clk>=0)
3322 {
3323
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83082 times.
83082 if(isSideViewGravity())
3324 {
3325 if(get_bit(quest_rules,qr_OLD_SIDEVIEW_LANDING_CODE))
3326 {
3327 if(!isOnSideviewPlatform())
3328 {
3329 bool willHitSVPlatform = false;
3330 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH)?hxsz:16;
3331 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT)?hysz:16;
3332 for(int32_t nx = x+4; nx < x+usewid; nx+=16)
3333 {
3334 if(fall > 0 && !IGNORE_SIDEVIEW_PLATFORMS && checkSVLadderPlatform(x+4,y+(fall/100)+usehei-1) && (((int32_t(y)+(int32_t(fall)/100)+usehei-1)&0xF0)!=((int32_t(y)+usehei-1)&0xF0)))
3335 {
3336 willHitSVPlatform = true;
3337 break;
3338 }
3339 }
3340 if(willHitSVPlatform)
3341 {
3342 y+=fall/100;
3343 //y-=int32_t(y)%16; //Fix to top of SV Ladder
3344 do_fix(y, 16); //Fix to top of SV Ladder
3345 fall = 0;
3346 }
3347 else
3348 {
3349 y+=fall/100;
3350 if(fall <= (int32_t)zinit.terminalv)
3351 fall += (zinit.gravity2/100);
3352 }
3353 }
3354 else
3355 {
3356 if(fall!=0) // Only fix pos once
3357 {
3358 //y-=(int32_t)y%8; // Fix position
3359 do_fix(y, 8); //Fix position
3360 }
3361
3362 fall = 0;
3363 }
3364 }
3365 else
3366 {
3367 if(isOnSideviewPlatform())
3368 fall = 0;
3369 else
3370 {
3371 zfix fall_amnt = fall/100;
3372 bool hit = false;
3373 while(fall_amnt >= 1)
3374 {
3375 --fall_amnt;
3376 ++y;
3377 if(isOnSideviewPlatform())
3378 {
3379 y = y.getInt();
3380 fall_amnt = 0;
3381 hit = true;
3382 break;
3383 }
3384 }
3385 if(fall_amnt > 0)
3386 y += fall_amnt;
3387 if(fall_amnt < 0)
3388 {
3389 if(!movexy(0,fall_amnt,spw_none))
3390 hit = true;
3391 }
3392 if(hit)
3393 fall = 0;
3394 else if(fall <= (int32_t)zinit.terminalv)
3395 fall += (zinit.gravity2/100);
3396 }
3397 }
3398 }
3399 else
3400 {
3401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83082 times.
83082 if (!(moveflags & FLAG_NO_FAKE_Z))
3402 {
3403
2/2
✓ Branch 0 taken 46180 times.
✓ Branch 1 taken 36902 times.
83082 if(fakefall!=0)
3404 36902 fakez-=(fakefall/100);
3405
3406
2/2
✓ Branch 0 taken 36902 times.
✓ Branch 1 taken 46180 times.
83082 if(fakez<0)
3407 36902 fakez = fakefall = 0;
3408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46180 times.
46180 else if(fakefall <= (int32_t)zinit.terminalv)
3409 46180 fakefall += (zinit.gravity2/100);
3410
3411
5/6
✓ Branch 0 taken 83082 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46180 times.
✓ Branch 3 taken 36902 times.
✓ Branch 4 taken 37010 times.
✓ Branch 5 taken 9170 times.
83082 if (fakez<=0 && fakefall > 0 && !get_bit(quest_rules, qr_FLUCTUATING_ENEMY_JUMP)) fakefall = 0;
3412 83082 }
3413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83082 times.
83082 if (!(moveflags & FLAG_NO_REAL_Z))
3414 {
3415
2/2
✓ Branch 0 taken 46180 times.
✓ Branch 1 taken 36902 times.
83082 if(fall!=0)
3416 36902 z-=(fall/100);
3417
3418
2/2
✓ Branch 0 taken 36902 times.
✓ Branch 1 taken 46180 times.
83082 if(z<0)
3419 36902 z = fall = 0;
3420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46180 times.
46180 else if(fall <= (int32_t)zinit.terminalv)
3421 46180 fall += (zinit.gravity2/100);
3422
3423
5/6
✓ Branch 0 taken 83082 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46180 times.
✓ Branch 3 taken 36902 times.
✓ Branch 4 taken 37010 times.
✓ Branch 5 taken 9170 times.
83082 if (z<=0 && fall > 0 && !get_bit(quest_rules, qr_FLUCTUATING_ENEMY_JUMP)) fall = 0;
3424 83082 }
3425
3426 }
3427 83082 }
3428
4/4
✓ Branch 0 taken 138890 times.
✓ Branch 1 taken 44432 times.
✓ Branch 2 taken 102459 times.
✓ Branch 3 taken 241349 times.
183322 if(!isSideViewGravity() && (moveflags & FLAG_CAN_PITFALL))
3429 {
3430
7/10
✓ Branch 0 taken 80553 times.
✓ Branch 1 taken 160796 times.
✓ Branch 2 taken 80553 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80553 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 80553 times.
✓ Branch 8 taken 80553 times.
✓ Branch 9 taken 80553 times.
241349 if(can_pitfall() && ((z <= 0 && fakez <= 0 && !isflier(id)) || (isflier(id) && (stunclk))) && !superman)
3431 {
3432 80553 fallCombo = check_pits();
3433 80553 }
3434 402455 }
3435
2/4
✓ Branch 0 taken 138890 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 138890 times.
✗ Branch 3 not taken.
227754 if(!isSideViewGravity() && (moveflags & FLAG_CAN_WATERDROWN))
3436 {
3437 if(can_pitfall() && ((z <= 0 && fakez <= 0 && !isflier(id)) || (isflier(id) && (stunclk))) && !superman)
3438 {
3439 drownCombo = check_water();
3440 }
3441 }
3442
3443 138890 runKnockback(); //scripted knockback handling
3444
3445 // clk is incremented here
3446
2/2
✓ Branch 0 taken 131579 times.
✓ Branch 1 taken 7311 times.
138890 if(++clk >= frate)
3447 7311 clk=0;
3448
3449 // hit and death handling
3450
2/2
✓ Branch 0 taken 134157 times.
✓ Branch 1 taken 4733 times.
138890 if(hclk>0)
3451 4733 --hclk;
3452
3453
2/2
✓ Branch 0 taken 134026 times.
✓ Branch 1 taken 4864 times.
138890 if(stunclk>0)
3454 4864 --stunclk;
3455
1/2
✓ Branch 0 taken 138890 times.
✗ Branch 1 not taken.
138890 if ( frozenclock > 0 )
3456 --frozenclock;
3457
3458
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 138890 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
138890 if(ceiling && z <= 0 && fakez <= 0)
3459 ceiling = false;
3460
3461 138890 try_death();
3462
3463 138890 scored=false;
3464
3465 138890 ++c_clk;
3466
3467 //Run its script
3468
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 138890 times.
138890 if (run_script(MODE_NORMAL)==RUNSCRIPT_SELFDELETE)
3469 {
3470 return 0; //Avoid NULLPO if this object deleted itself
3471 }
3472
3473 // returns true when enemy is defeated
3474 138890 return Dead(index);
3475 138890 }
3476
3477 143094 bool enemy::setSolid(bool set)
3478 {
3479
1/2
✓ Branch 0 taken 143094 times.
✗ Branch 1 not taken.
143094 bool actual = set && !isSubmerged();
3480 143094 bool ret = solid_object::setSolid(actual);
3481 143094 solid = set;
3482 143094 return ret;
3483 }
3484 void enemy::doContactDamage(int32_t hdir)
3485 {
3486 Hero.hithero(guys.find(this), hdir);
3487 }
3488
3489 void enemy::solid_push(solid_object *obj)
3490 {
3491 if(obj == this) return; //can't push self
3492 if(moveflags&FLAG_NOT_PUSHABLE) return; //not pushable
3493 zfix dx, dy;
3494 int32_t hdir = -1;
3495 solid_push_int(obj,dx,dy,hdir);
3496
3497 if(!dx && !dy) return;
3498
3499 bool t = obj->getTempNonsolid();
3500 obj->setTempNonsolid(true);
3501
3502 int32_t ydir = dy > 0 ? down : up;
3503 int32_t xdir = dx > 0 ? right : left;
3504
3505 auto special = isflier(id) ? spw_floater : spw_none;
3506 if(!movexy(dx,dy,special,true,true))
3507 {
3508 //Crushed?
3509 }
3510
3511 obj->setTempNonsolid(t);
3512 }
3513 bool enemy::is_unpushable() const
3514 {
3515 return isSubmerged();
3516 }
3517 bool enemy::sideview_mode() const
3518 {
3519 return isSideViewGravity() && (moveflags&FLAG_OBEYS_GRAV) && !(moveflags&FLAG_NOT_PUSHABLE);
3520 }
3521
3522 bool enemy::m_walkflag_old(int32_t dx,int32_t dy,int32_t special, int32_t x, int32_t y)
3523 {
3524 int32_t yg = (special==spw_floater)?8:0;
3525 int32_t nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
3526
3527 if(dx<16-nb || dy<zc_max(16-yg-nb,0) || dx>=240+nb || dy>=160+nb)
3528 return true;
3529
3530 bool isInDungeon = isdungeon();
3531 if(isInDungeon || special==spw_wizzrobe)
3532 {
3533 if((x>=32 && dy<32-yg) || (y>-1000 && y<=144 && dy>=144))
3534 return true;
3535
3536 if((x>=32 && dx<32) || (x>-1000 && x<224 && dx>=224))
3537 if(special!=spw_door) // walk in door way
3538 return true;
3539 }
3540
3541 if(!(moveflags & FLAG_CAN_PITWALK) && !(moveflags & FLAG_CAN_PITFALL)) //Don't walk into pits (knockback doesn't call this func)
3542 {
3543 if(ispitfall(dx,dy) || ispitfall(dx+8,dy)
3544 || ispitfall(dx,dy+8) || ispitfall(dx+8,dy+8))
3545 return true;
3546 }
3547
3548 switch(special)
3549 {
3550 case spw_clipbottomright:
3551 if(dy>=128 || dx>=208) return true;
3552 break;
3553 case spw_clipright:
3554 break; //if(x>=208) return true; break;
3555
3556 case spw_wizzrobe: // fall through
3557 case spw_floater: // Special case for fliers and wizzrobes - hack!
3558 {
3559 if(isInDungeon)
3560 {
3561 if(dy < 32-yg || dy >= 144) return true;
3562 if(dx < 32 || dx >= 224) return true;
3563 }
3564 return false;
3565 }
3566 }
3567
3568 dx&=(special==spw_halfstep)?(~7):(~15);
3569 dy&=(special==spw_halfstep || isSideViewGravity())?(~7):(~15);
3570
3571 if(special==spw_water)
3572 return (water_walkflag(dx,dy+8,1) || water_walkflag(dx+8,dy+8,1));
3573
3574 return _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3575 groundblocked(dx,dy+8) || groundblocked(dx+8,dy+8);
3576 }
3577
3578 bool enemy::m_walkflag_simple(int32_t dx,int32_t dy)
3579 {
3580 bool kb = false;
3581 int32_t nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
3582
3583 if(dx<16-nb || dy<zc_max(16-nb,0) || dx>=240+nb || dy>=160+nb)
3584 return true;
3585
3586 if(isdungeon())
3587 {
3588 if((dy<32) || (dy>=144))
3589 return true;
3590
3591 if((dx<32) || (dx>=224))
3592 return true;
3593 }
3594
3595 if(!(moveflags & FLAG_CAN_PITWALK) && (!(moveflags & FLAG_CAN_PITFALL))) //Don't walk into pits, unless being knocked back
3596 {
3597 if(ispitfall(dx,dy) || ispitfall(dx+8,dy)
3598 || ispitfall(dx,dy+8) || ispitfall(dx+8,dy+8))
3599 return true;
3600 }
3601
3602 if(get_bit(quest_rules,qr_ENEMY_BROKEN_TOP_HALF_SOLIDITY))
3603 {
3604 return _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3605 groundblocked(dx,dy+8,kb) || groundblocked(dx+8,dy+8,kb);
3606 }
3607 else
3608 {
3609 return _walkflag(dx,dy,1) || _walkflag(dx+8,dy,1) ||
3610 _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3611 groundblocked(dx,dy,kb) || groundblocked(dx+8,dy,kb) ||
3612 groundblocked(dx,dy+8,kb) || groundblocked(dx+8,dy+8,kb);
3613 }
3614 }
3615
3616 220108 bool enemy::m_walkflag(int32_t dx,int32_t dy,int32_t special, int32_t dir, int32_t input_x, int32_t input_y, bool kb)
3617 {
3618
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 220108 times.
220108 if(moveflags & FLAG_USE_NEW_MOVEMENT)
3619 return scr_walkflag(dx,dy,special,dir,input_x,input_y,kb);
3620 220108 int32_t yg = (special==spw_floater)?8:0;
3621 220108 int32_t nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
3622
2/2
✓ Branch 0 taken 21089 times.
✓ Branch 1 taken 199019 times.
220108 switch(dir)
3623 {
3624 case l_down:
3625 case r_down:
3626 case down:
3627 case 11: //r_down
3628 case 12: //down
3629 case 13: //l_down
3630 {
3631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21089 times.
21089 if ( ((unsigned)(id&0xFFF)) < MAXGUYS )
3632 {
3633
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 21089 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
21089 if ( SIZEflags&guyflagOVERRIDE_HIT_HEIGHT && !isflier(id) )
3634 {
3635 //Small enemies are treated as 16x16, for the purposes of m_walkflag!
3636 dy += zc_max(hysz-16,0);
3637 }
3638 21089 }
3639 21089 break;
3640 }
3641 }
3642
2/2
✓ Branch 0 taken 19790 times.
✓ Branch 1 taken 200318 times.
220108 switch(dir)
3643 {
3644 case r_up:
3645 case r_down:
3646 case right:
3647 case 9: //r_up
3648 case 10: //right
3649 case 11: //r_down
3650 {
3651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19790 times.
19790 if ( ((unsigned)(id&0xFFF)) < MAXGUYS )
3652 {
3653
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19790 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19790 if ( SIZEflags&guyflagOVERRIDE_HIT_WIDTH && !isflier(id) )
3654 {
3655 //Small enemies are treated as 16x16, for the purposes of m_walkflag!
3656 dx += zc_max(hxsz-16,0);
3657 }
3658 19790 }
3659 19790 break;
3660 }
3661 }
3662 //Z_eventlog("Checking x,y %d,%d\n",dx,dy);
3663
3664
10/10
✓ Branch 0 taken 173380 times.
✓ Branch 1 taken 46728 times.
✓ Branch 2 taken 22033 times.
✓ Branch 3 taken 24695 times.
✓ Branch 4 taken 46702 times.
✓ Branch 5 taken 26 times.
✓ Branch 6 taken 46640 times.
✓ Branch 7 taken 62 times.
✓ Branch 8 taken 173506 times.
✓ Branch 9 taken 220146 times.
220108 if(dx<16-nb || dy<zc_max(16-yg-nb,0) || dx>=240+nb || dy>=160+nb)
3665 346974 return true;
3666
3667 220146 bool isInDungeon = isdungeon();
3668
3/4
✓ Branch 0 taken 2252 times.
✓ Branch 1 taken 217894 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2252 times.
220146 if(isInDungeon || special==spw_wizzrobe)
3669 {
3670
8/8
✓ Branch 0 taken 44314 times.
✓ Branch 1 taken 173580 times.
✓ Branch 2 taken 43450 times.
✓ Branch 3 taken 864 times.
✓ Branch 4 taken 44050 times.
✓ Branch 5 taken 130394 times.
✓ Branch 6 taken 44049 times.
✓ Branch 7 taken 1 times.
217894 if((input_x>=32 && dy<32-yg) || (input_y>-1000 && input_y<=144 && dy>=144))
3671 87499 return true;
3672
3673
7/8
✓ Branch 0 taken 43716 times.
✓ Branch 1 taken 86679 times.
✓ Branch 2 taken 43331 times.
✓ Branch 3 taken 385 times.
✓ Branch 4 taken 43634 times.
✓ Branch 5 taken 43430 times.
✓ Branch 6 taken 43634 times.
✗ Branch 7 not taken.
130395 if((input_x>=32 && dx<32) || (input_x>-1000 && input_x<224 && dx>=224))
3674
1/2
✓ Branch 0 taken 303 times.
✗ Branch 1 not taken.
86965 if(special!=spw_door) // walk in door way
3675 303 return true;
3676 43430 }
3677
3678
5/6
✓ Branch 0 taken 4235 times.
✓ Branch 1 taken 41447 times.
✓ Branch 2 taken 4235 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 610 times.
✓ Branch 5 taken 3625 times.
45682 if(!(moveflags & FLAG_CAN_PITWALK) && (!(moveflags & FLAG_CAN_PITFALL) || !kb)) //Don't walk into pits, unless being knocked back
3679 {
3680
2/4
✓ Branch 0 taken 3625 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3625 times.
7250 if(ispitfall(dx,dy) || ispitfall(dx+8,dy)
3681
2/4
✓ Branch 0 taken 3625 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3625 times.
✗ Branch 3 not taken.
3625 || ispitfall(dx,dy+8) || ispitfall(dx+8,dy+8))
3682 return true;
3683 3625 }
3684
3685
3/4
✓ Branch 0 taken 41429 times.
✓ Branch 1 taken 4251 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
45682 switch(special)
3686 {
3687 case spw_clipbottomright:
3688 if(dy>=128 || dx>=208) return true;
3689 break;
3690 case spw_clipright:
3691 2 break; //if(input_x>=208) return true; break;
3692
3693 case spw_wizzrobe: // fall through
3694 case spw_floater: // Special case for fliers and wizzrobes - hack!
3695 {
3696
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41429 times.
41429 if(isInDungeon)
3697 {
3698
2/4
✓ Branch 0 taken 41429 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 41429 times.
41429 if(dy < 32-yg || dy >= 144) return true;
3699
3/4
✓ Branch 0 taken 41419 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 41419 times.
41429 if(dx < 32 || dx >= 224) return true;
3700 41419 }
3701 41419 return false;
3702 }
3703 }
3704
3705 4253 dx&=(special==spw_halfstep)?(~7):(~15);
3706
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4247 times.
4253 dy&=(special==spw_halfstep || isSideViewGravity())?(~7):(~15);
3707
3708
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4253 times.
4253 if(special==spw_water)
3709 return (water_walkflag(dx,dy+8,1) || water_walkflag(dx+8,dy+8,1));
3710
3711
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 557 times.
4253 if(get_bit(quest_rules,qr_ENEMY_BROKEN_TOP_HALF_SOLIDITY))
3712 {
3713
4/4
✓ Branch 0 taken 2835 times.
✓ Branch 1 taken 861 times.
✓ Branch 2 taken 2776 times.
✓ Branch 3 taken 59 times.
6472 return _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3714
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2776 times.
2776 groundblocked(dx,dy+8,kb) || groundblocked(dx+8,dy+8,kb);
3715 }
3716 else
3717 {
3718
4/4
✓ Branch 0 taken 489 times.
✓ Branch 1 taken 68 times.
✓ Branch 2 taken 467 times.
✓ Branch 3 taken 22 times.
1024 return _walkflag(dx,dy,1) || _walkflag(dx+8,dy,1) ||
3719
4/4
✓ Branch 0 taken 438 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 436 times.
✓ Branch 3 taken 2 times.
467 _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3720
3/4
✓ Branch 0 taken 368 times.
✓ Branch 1 taken 68 times.
✓ Branch 2 taken 368 times.
✗ Branch 3 not taken.
436 groundblocked(dx,dy,kb) || groundblocked(dx+8,dy,kb) ||
3721
1/2
✓ Branch 0 taken 368 times.
✗ Branch 1 not taken.
368 groundblocked(dx,dy+8,kb) || groundblocked(dx+8,dy+8,kb);
3722 }
3723 46798 }
3724
3725 bool enemy::isOnSideviewPlatform()
3726 {
3727 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ? hxsz : 16;
3728 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ? hysz : 16;
3729 if(y + usehei >= 176 && currscr>=0x70 && !(tmpscr->flags2&wfDOWN)) return true; //Bottom of the map
3730 if(check_slope(x, y+1, usewid, usehei)) return true;
3731 for(int32_t nx = x + 4; nx <= x + usewid - 4; nx+=16)
3732 {
3733 if(_walkflag(nx,y+usehei,1)) return true;
3734 if(IGNORE_SIDEVIEW_PLATFORMS || ((int32_t(y)+usehei)%16)!=0) continue;
3735 if(checkSVLadderPlatform(nx,y+usehei)) return true;
3736 }
3737 return false;
3738 }
3739
3740 // Stops playing the given sound only if there are no enemies left to play it
3741 4699 void enemy::stop_bgsfx(int32_t index)
3742 {
3743
2/2
✓ Branch 0 taken 4661 times.
✓ Branch 1 taken 38 times.
4699 if(bgsfx<=0)
3744 4661 return;
3745
3746 // Look for other enemies with the same bgsfx
3747
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 38 times.
76 for(int32_t i=0; i<guys.Count(); i++)
3748 {
3749
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
38 if(i!=index && ((enemy*)guys.spr(i))->bgsfx==bgsfx)
3750 return;
3751 38 }
3752
3753 38 stop_sfx(bgsfx);
3754 4699 }
3755
3756
3757 // to allow for different sfx on defeating enemy
3758 247 void enemy::death_sfx()
3759 {
3760
1/2
✓ Branch 0 taken 247 times.
✗ Branch 1 not taken.
247 if(deadsfx > 0) sfx(deadsfx,pan(int32_t(x)));
3761 247 }
3762
3763 void enemy::move(zfix dx,zfix dy)
3764 {
3765 /*if(FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && FFCore.getQuestHeaderInfo(vBuild) >= 50 )
3766 {
3767 switch(family)
3768 {
3769 case eeFIRE:
3770 case eeOTHER:
3771 return;
3772 default: break;
3773 }
3774 if(family >= eeSCRIPT01 && family <= eeFFRIENDLY10 ) return;
3775 }
3776 */
3777 if(!watch && (!(isSideViewGravity()) || isOnSideviewPlatform() || !(moveflags & FLAG_OBEYS_GRAV) || !enemycanfall(id)))
3778 {
3779 x+=dx;
3780 y+=dy;
3781 }
3782 }
3783
3784 79551 void enemy::move(zfix s)
3785 {
3786 /*if(FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && FFCore.getQuestHeaderInfo(vBuild) >= 50 )
3787 {
3788 switch(family)
3789 {
3790 case eeFIRE:
3791 case eeOTHER:
3792 return;
3793 default: break;
3794 }
3795 if(family >= eeSCRIPT01 && family <= eeFFRIENDLY10 ) return;
3796 }*/
3797
2/10
✓ Branch 0 taken 79551 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 79551 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
79551 if(!watch && (!(isSideViewGravity()) || isOnSideviewPlatform() || !enemycanfall(id) || !(moveflags & FLAG_OBEYS_GRAV)))
3798 {
3799 79551 sprite::move(s);
3800 79551 }
3801 79551 }
3802
3803 247 void enemy::leave_item()
3804 {
3805 247 int32_t drop_item = select_dropitem(item_set, x, y);
3806 247 int32_t thedropset = item_set;
3807
3808 247 std::vector<int32_t> &ev = FFCore.eventData;
3809 247 ev.clear();
3810 247 ev.push_back(getUID());
3811 247 ev.push_back(drop_item*10000);
3812 247 ev.push_back(thedropset*10000);
3813
3814 247 throwGenScriptEvent(GENSCR_EVENT_ENEMY_DROP_ITEM_1);
3815 247 drop_item = vbound(ev[1] / 10000,-2,255);
3816 247 thedropset = ev[2] / 10000;
3817 247 ev.clear();
3818
1/2
✓ Branch 0 taken 247 times.
✗ Branch 1 not taken.
247 if(drop_item == -2)
3819 {
3820 drop_item = select_dropitem(thedropset,x,y);
3821 }
3822
3823
3/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 157 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 90 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
247 if(drop_item>=0&&((itemsbuf[drop_item].family!=itype_fairy)||!m_walkflag(x,y,0,dir)))
3824 {
3825 item* itm;
3826
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 90 times.
90 if (get_bit(quest_rules, qr_ENEMY_DROPS_USE_HITOFFSETS))
3827 {
3828 itm = (new item(x+hxofs+(hxsz/2)-8,y+hyofs+(hysz/2)-8,(zfix)0,drop_item,ipBIGRANGE+ipTIMER,0));
3829 }
3830 else
3831 {
3832
1/14
✗ Branch 0 not taken.
✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
90 if(extend >= 3) itm = (new item(x+(txsz-1)*8,y+(tysz-1)*8,(zfix)0,drop_item,ipBIGRANGE+ipTIMER,0));
3833
4/8
✓ Branch 0 taken 90 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 90 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 90 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 90 times.
✗ Branch 7 not taken.
90 else itm = (new item(x,y,(zfix)0,drop_item,ipBIGRANGE+ipTIMER,0));
3834 }
3835 90 itm->from_dropset = thedropset;
3836 90 items.add(itm);
3837
3838 90 ev.push_back(getUID());
3839 90 ev.push_back(itm->getUID());
3840
3841 90 throwGenScriptEvent(GENSCR_EVENT_ENEMY_DROP_ITEM_2);
3842 90 ev.clear();
3843 90 }
3844 247 }
3845
3846 // auomatically kill off enemy (for rooms with ringleaders)
3847 void enemy::kickbucket()
3848 {
3849 if(!superman)
3850 hp=-1000; // don't call death_sfx()
3851 }
3852
3853 bool enemy::isSubmerged() const
3854 {
3855 return submerged;
3856 //!TODO SOLIDPUSH more things like teleporting wizzrobes
3857 }
3858
3859 void enemy::FireBreath(bool seekhero)
3860 {
3861 if(wpn==wNone)
3862 return;
3863
3864 if(wpn==ewFireTrail)
3865 {
3866 dmisc1 = e1tEACHTILE;
3867 FireWeapon();
3868 return;
3869 }
3870
3871 float fire_angle=0.0;
3872 int32_t wx=0, wy=0, wdir=dir;
3873
3874 if(!seekhero)
3875 {
3876 switch(dir)
3877 {
3878 case down:
3879 fire_angle=PI*(int64_t(zc_oldrand()%20)+10)/40;
3880 wx=x;
3881 wy=y+8;
3882 break;
3883
3884 case -1:
3885 case up:
3886 fire_angle=PI*(int64_t(zc_oldrand()%20)+50)/40;
3887 wx=x;
3888 wy=y-8;
3889 break;
3890
3891 case left:
3892 fire_angle=PI*(int64_t(zc_oldrand()%20)+30)/40;
3893 wx=x-8;
3894 wy=y;
3895 break;
3896
3897 case right:
3898 fire_angle=PI*(int64_t(zc_oldrand()%20)+70)/40;
3899 wx=x+8;
3900 wy=y;
3901 break;
3902 }
3903
3904 if(wpn==ewFlame || wpn==ewFlame2)
3905 {
3906 if(fire_angle==-PI || fire_angle==PI) wdir=left;
3907 else if(fire_angle==-PI/2) wdir=up;
3908 else if(fire_angle==PI/2) wdir=down;
3909 else if(fire_angle==0) wdir=right;
3910 else if(fire_angle<-PI/2) wdir=l_up;
3911 else if(fire_angle<0) wdir=r_up;
3912 else if(fire_angle<(PI/2)) wdir=r_down;
3913 else if(fire_angle<PI) wdir=l_down;
3914 }
3915 }
3916 else
3917 {
3918 wx = x;
3919 wy = y;
3920 }
3921
3922 addEwpn(wx,wy,z,wpn,2,wdp,seekhero ? 0xFF : wdir, getUID(), 0, fakez);
3923 sfx(wpnsfx(wpn),pan(int32_t(x)));
3924
3925 int32_t i=Ewpns.Count()-1;
3926 weapon *ew = (weapon*)(Ewpns.spr(i));
3927 ew->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
3928
3929 if(!seekhero && (zc_oldrand()&4))
3930 {
3931 ew->angular=true;
3932 ew->angle=fire_angle;
3933 }
3934
3935 if(wpn==ewFlame && wpnsbuf[ewFLAME].frames>1)
3936 {
3937 ew->aframe=zc_oldrand()%wpnsbuf[ewFLAME].frames;
3938 if ( ew->do_animation ) ew->tile+=ew->aframe;
3939 }
3940
3941 for(int32_t j=Ewpns.Count()-1; j>0; j--)
3942 {
3943 Ewpns.swap(j,j-1);
3944 }
3945 }
3946
3947 189 void enemy::FireWeapon()
3948 {
3949 /*
3950 * Type:
3951 * 0x01: Boss fireball
3952 * 0x02: Seeks Hero
3953 * 0x04: Fast projectile
3954 * 0x00-0x30: If 0x02, slants toward (type>>3)-1
3955 */
3956
3957
1/2
✓ Branch 0 taken 189 times.
✗ Branch 1 not taken.
189 if (wpn < 1) return;
3958
1/10
✗ Branch 0 not taken.
✓ Branch 1 taken 189 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
189 if(wpn<wEnemyWeapons && dmisc1!=9 && dmisc1!=10 && (wpn < wScript1 && wpn > wScript10) ) // Summoning doesn't require weapons
3959 return;
3960
3961
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 189 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
189 if(wpn==ewFireTrail && dmisc1>=e1t3SHOTS && dmisc1<=e1t8SHOTS)
3962 dmisc1 = e1tEACHTILE;
3963
3964 189 int32_t xoff = 0;
3965 189 int32_t yoff = 0;
3966
1/2
✓ Branch 0 taken 189 times.
✗ Branch 1 not taken.
189 if ( SIZEflags&guyflagOVERRIDE_HIT_WIDTH )
3967 {
3968 xoff += (hxsz/2)-8;
3969 //Z_scripterrlog("width flag enabled. xoff = %d\n", xoff);
3970 }
3971
1/2
✓ Branch 0 taken 189 times.
✗ Branch 1 not taken.
189 if ( SIZEflags&guyflagOVERRIDE_HIT_HEIGHT )
3972 {
3973 yoff += (hysz/2)-8;
3974 //Z_scripterrlog("width flag enabled. yoff = %d\n", yoff);
3975 }
3976
3977
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 189 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
189 switch(dmisc1)
3978 {
3979 case e1t5SHOTS: //BS-Aquamentus
3980 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^left)+5)<<3),wdp,dir,-1, getUID(),false));
3981 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3982 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^right)+5)<<3),wdp,dir,-1, getUID(),false));
3983 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3984
3985 [[fallthrough]];
3986 case e1t3SHOTSFAST:
3987 case e1t3SHOTS: //Aquamentus
3988 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^left)+1)<<3)+(dmisc1==e1t3SHOTSFAST ? 4:0),wdp,dir,-1, getUID(),false));
3989 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3990 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^right)+1)<<3)+(dmisc1==e1t3SHOTSFAST ? 4:0),wdp,dir,-1, getUID(),false));
3991 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3992
3993 [[fallthrough]];
3994 default:
3995
11/20
✓ Branch 0 taken 189 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 189 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 189 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 189 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 189 times.
✓ Branch 12 taken 189 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 186 times.
✓ Branch 16 taken 189 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 189 times.
✗ Branch 19 not taken.
189 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(dmisc1==e1t3SHOTSFAST || dmisc1==e1tFAST ? 4:0),wdp,wpn==ewFireball2 || wpn==ewFireball ? 0:dir,-1, getUID(),false));
3996 189 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3997 189 sfx(wpnsfx(wpn),pan(int32_t(x)));
3998 189 break;
3999
4000 case e1tSLANT:
4001 {
4002 int32_t slant = 0;
4003
4004 if(((Hero.x-x) < -8 && dir==up) || ((Hero.x-x) > 8 && dir==down) || ((Hero.y-y) < -8 && dir==left) || ((Hero.y-y) > 8 && dir==right))
4005 slant = left;
4006 else if(((Hero.x-x) > 8 && dir==up) || ((Hero.x-x) < -8 && dir==down) || ((Hero.y-y) > 8 && dir==left) || ((Hero.y-y) < -8 && dir==right))
4007 slant = right;
4008
4009 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^slant)+1)<<3),wdp,wpn==ewFireball2 || wpn==ewFireball ? 0:dir,-1, getUID(),false));
4010 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4011 sfx(wpnsfx(wpn),pan(int32_t(x)));
4012 break;
4013 }
4014
4015 case e1t8SHOTS: //Fire Wizzrobe
4016 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,l_up,-1, getUID(),false));
4017 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4018 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4019 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,l_down,-1, getUID(),false));
4020 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4021 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4022 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,r_up,-1, getUID(),false));
4023 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4024 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4025 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,r_down,-1, getUID(),false));
4026 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4027 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4028
4029 [[fallthrough]];
4030 case e1t4SHOTS: //Stalfos 3
4031 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,up,-1, getUID(),false));
4032 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4033 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4034 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,down,-1, getUID(),false));
4035 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4036 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4037 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,left,-1, getUID(),false));
4038 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4039 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4040 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,right,-1, getUID(),false));
4041 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4042 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4043 sfx(wpnsfx(wpn),pan(int32_t(x)));
4044 break;
4045
4046 case e1tSUMMON: // Bat Wizzrobe
4047 {
4048 //al_trace("Summon Bats\n");
4049 //zprint2("Summon Bats\n");
4050 if(dmisc4==0) break; // Summon 0
4051
4052 int32_t bc=0;
4053
4054 for(int32_t gc=0; gc<guys.Count(); gc++)
4055 {
4056 if((((enemy*)guys.spr(gc))->id) == dmisc3)
4057 {
4058 ++bc;
4059 }
4060 }
4061
4062 if(bc<=40) // Not too many enemies
4063 {
4064 int32_t kids = guys.Count();
4065 int32_t bats=(zc_oldrand()%zc_max(1,dmisc4))+1;
4066
4067 for(int32_t i=0; i<bats; i++)
4068 {
4069 //zprint2("summon\n");
4070 //al_trace("summon\n");
4071 if(addchild(x,y,dmisc3,-10, this->script_UID))
4072 {
4073 ((enemy*)guys.spr(kids+i))->count_enemy = false;
4074 //((enemy*)guys.spr(guys.Count()-1))->parent_script_UID = this->script_UID;
4075 //zprint2("Summoner Script UID: %d\n",this->script_UID);
4076
4077 }
4078 }
4079
4080 sfx(get_bit(quest_rules,qr_MORESOUNDS) ? WAV_ZN1SUMMON : WAV_FIRE,pan(int32_t(x)));
4081 }
4082
4083 break;
4084 }
4085
4086 case e1tSUMMONLAYER: // Summoner
4087 {
4088 if(count_layer_enemies()==0)
4089 {
4090 break;
4091 }
4092
4093 int32_t kids = guys.Count();
4094
4095 if(kids<40)
4096 {
4097 int32_t newguys=(zc_oldrand()%3)+1;
4098 bool summoned=false;
4099
4100 for(int32_t i=0; i<newguys; i++)
4101 {
4102 int32_t id2=vbound(random_layer_enemy(),eSTART,eMAXGUYS-1);
4103 int32_t x2=0;
4104 int32_t y2=0;
4105
4106 for(int32_t k=0; k<20; ++k)
4107 {
4108 x2=16*((zc_oldrand()%12)+2);
4109 y2=16*((zc_oldrand()%7)+2);
4110
4111 if((!m_walkflag(x2,y2,0,dir))&&((abs(x2-Hero.getX())>=32)||(abs(y2-Hero.getY())>=32)))
4112 {
4113 //zprint2("summon\n");
4114 //al_trace("summon\n");
4115 if(addchild(x2,y2,get_bit(quest_rules,qr_ENEMIESZAXIS) ? 64 : 0,id2,-10, this->script_UID))
4116 {
4117 ((enemy*)guys.spr(kids+i))->count_enemy = false;
4118 //((enemy*)guys.spr(guys.Count()-1))->parent_script_UID = this->script_UID;
4119 if (get_bit(quest_rules,qr_ENEMIESZAXIS) && (((enemy*)guys.spr(kids+i))->moveflags & FLAG_USE_FAKE_Z))
4120 {
4121 ((enemy*)guys.spr(kids+i))->fakez = 64;
4122 ((enemy*)guys.spr(kids+i))->z = 0;
4123 }
4124 }
4125
4126 summoned=true;
4127 break;
4128 }
4129 }
4130 }
4131
4132 if(summoned)
4133 {
4134 sfx(get_bit(quest_rules,qr_MORESOUNDS) ? WAV_ZN1SUMMON : WAV_FIRE,pan(int32_t(x)));
4135 }
4136 }
4137
4138 break;
4139 }
4140 }
4141 189 }
4142
4143
4144 // Hit the shield(s)?
4145 // Apparently, this function is only used for hookshots...
4146 bool enemy::hitshield(int32_t wpnx, int32_t wpny, int32_t xdir)
4147 {
4148 if(!(family==eeWALK || family==eeFIRE || family==eeOTHER))
4149 return false;
4150
4151 bool ret = false;
4152
4153 // TODO: There must be some bitwise operations that can simplify this...
4154 if(wpny > y) ret = ((flags&inv_front && xdir==down) || (flags&inv_back && xdir==up) || (flags&inv_left && xdir==left) || (flags&inv_right && xdir==right));
4155 else if(wpny < y) ret = ((flags&inv_front && xdir==up) || (flags&inv_back && xdir==down) || (flags&inv_left && xdir==right) || (flags&inv_right && xdir==left));
4156
4157 if(wpnx < x) ret = ret || ((flags&inv_front && xdir==left) || (flags&inv_back && xdir==right) || (flags&inv_left && xdir==up) || (flags&inv_right && xdir==down));
4158 else if(wpnx > x) ret = ret || ((flags&inv_front && xdir==right) || (flags&inv_back && xdir==left) || (flags&inv_left && xdir==down) || (flags&inv_right && xdir==up));
4159
4160 return ret;
4161 }
4162
4163
4164 //! Weapon Editor for 2.6
4165 //To hell with this. I'm writing new functions to resolve weapon type and defence. -Z
4166
4167
4168 //converts a wqeapon ID to its defence index.
4169 607 int32_t weaponToDefence(int32_t wid)
4170 {
4171
3/44
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 175 times.
✓ Branch 3 taken 151 times.
✓ Branch 4 taken 281 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
607 switch(wid)
4172 {
4173 case wNone: return -1;
4174 175 case wSword: return edefSWORD;
4175 151 case wBeam: return edefBEAM;
4176 281 case wBrang: return edefBRANG;
4177 case wBomb: return edefBOMB;
4178 case wSBomb: return edefSBOMB;
4179 case wLitBomb: return edefBOMB;
4180 case wLitSBomb: return edefSBOMB;
4181 case wArrow: return edefARROW;
4182 case wFire: return edefFIRE;
4183 case wWhistle:
4184 {
4185 //al_trace("Weapon resolved as a whistle, using edef: %s\n", "edefWhistle");
4186 return edefWhistle;
4187 }
4188 case wBait: return edefBAIT;
4189 case wWand: return edefWAND;
4190 case wMagic: return edefMAGIC;
4191 case wCatching: return -1;
4192 case wWind: return edefWIND;
4193 case wRefMagic: return edefREFMAGIC;
4194 case wRefFireball: return edefREFBALL;
4195 case wRefRock: return edefREFROCK;
4196 case wHammer: return edefHAMMER;
4197 case wHookshot: return edefHOOKSHOT;
4198 case wHSHandle: return edefHOOKSHOT;
4199 case wHSChain: return edefHOOKSHOT;
4200 case wSSparkle: return edefSPARKLE;
4201 case wFSparkle: return edefSPARKLE;
4202 case wSmack: return -1; // is this the candle object?
4203 case wPhantom: return -1; //engine created visual effects.
4204 case wCByrna: return edefBYRNA;
4205 case wRefBeam: return edefREFBEAM;
4206 case wStomp: return edefSTOMP;
4207 case wScript1: return edefSCRIPT01;
4208 case wScript2: return edefSCRIPT02;
4209 case wScript3: return edefSCRIPT03;
4210 case wScript4: return edefSCRIPT04;
4211 case wScript5: return edefSCRIPT05;
4212 case wScript6: return edefSCRIPT06;
4213 case wScript7: return edefSCRIPT07;
4214 case wScript8: return edefSCRIPT08;
4215 case wScript9: return edefSCRIPT09;
4216 case wScript10: return edefSCRIPT10;
4217 case wIce: return edefICE;
4218 case wSound: return edefSONIC;
4219 case wThrown: return edefTHROWN;
4220 //case wPot: return edefPOT;
4221 // case wLitZap: return edefELECTRIC;
4222 // case wZ3Sword: return edefZ3SWORD;
4223 // case wLASWord: return edefLASWORD;
4224 // case wSpinAttk: return edefSPINATTK;
4225 // case wShield: return edefSHIELD;
4226 // case wTrowel: return edefTROWEL;
4227
4228 default: return -1;
4229 }
4230 607 }
4231
4232 607 int32_t getDefType(weapon *w)
4233 {
4234 607 int32_t id = getWeaponID(w);
4235 607 int32_t edef = weaponToDefence(id);
4236
1/2
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
607 if(edef == edefHOOKSHOT)
4237 {
4238 if(w->family_class == itype_switchhook)
4239 return edefSwitchHook;
4240 }
4241 607 return edef;
4242 607 }
4243
4244 933 int32_t getWeaponID(weapon *w)
4245 {
4246 933 int32_t usewpn = w->useweapon;
4247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 933 times.
933 return (usewpn > 0) ? usewpn : w->id;
4248 }
4249
4250 607 int32_t enemy::resolveEnemyDefence(weapon *w)
4251 {
4252 //sword edef is 9, but we're reading it at 0
4253 //,
4254 607 int32_t weapondef = 0;
4255 607 int32_t wdeftype = getDefType(w);
4256 607 int32_t usedef = w->usedefence;
4257
4258
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
607 if ( usedef > 0 && (wdeftype < 0 || wdeftype >= edefLAST255 || defense[wdeftype] == 0))
4259 {
4260 weapondef = usedef*-1;
4261 }
4262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 else if(unsigned(wdeftype) < edefLAST255)
4263 {
4264 607 weapondef = wdeftype;
4265 607 }
4266 607 return weapondef;
4267 }
4268
4269 627 byte get_def_ignrflag(int32_t edef)
4270 {
4271
1/3
✓ Branch 0 taken 627 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
627 switch(edef)
4272 {
4273 case edIGNORE:
4274 case edIGNOREL1:
4275 case edSTUNORIGNORE:
4276 return WPNUNB_IGNR;
4277 case edSTUNORCHINK:
4278 case edCHINK:
4279 case edCHINKL1:
4280 case edCHINKL2:
4281 case edCHINKL4:
4282 case edCHINKL6:
4283 case edCHINKL8:
4284 case edCHINKL10:
4285 case edLEVELCHINK2:
4286 case edLEVELCHINK3:
4287 case edLEVELCHINK4:
4288 case edLEVELCHINK5:
4289 return WPNUNB_BLOCK;
4290 }
4291 627 return 0;
4292 627 }
4293
4294 627 int32_t conv_edef_unblockable(int32_t edef, byte unblockable)
4295 {
4296
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
627 if(!(unblockable&get_def_ignrflag(edef))) return edef;
4297 switch(edef)
4298 {
4299 case edIGNORE:
4300 case edIGNOREL1:
4301 case edCHINK:
4302 case edCHINKL1:
4303 case edCHINKL2:
4304 case edCHINKL4:
4305 case edCHINKL6:
4306 case edCHINKL8:
4307 case edCHINKL10:
4308 case edLEVELCHINK2:
4309 case edLEVELCHINK3:
4310 case edLEVELCHINK4:
4311 case edLEVELCHINK5:
4312 return edNORMAL;
4313 case edSTUNORIGNORE:
4314 case edSTUNORCHINK:
4315 return edSTUNONLY;
4316 }
4317 return edef;
4318 627 }
4319
4320 // Do we do damage?
4321 // 0: takehit returns 0
4322 // 1: takehit returns 1
4323 // -1: do damage
4324 //The input from resolveEnemyDefence() for the param 'edef' is negative if a specific defence RESULT is being used.
4325 607 int32_t enemy::defendNew(int32_t wpnId, int32_t *power, int32_t edef, byte unblockable) //May need *wpn to set return on brangs and hookshots
4326 {
4327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 if(switch_hooked) return 0;
4328 607 int32_t tempx = x;
4329 607 int32_t tempy = y;
4330 607 int32_t the_defence = 0;
4331
1/2
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
607 if ( edef < 0 ) //we are using a specific base default defence for a weapon
4332 {
4333 the_defence = edef*-1; //A specific defence type.
4334 }
4335 607 else the_defence = defense[edef];
4336
4337 607 the_defence = conv_edef_unblockable(the_defence, unblockable);
4338
4339
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
607 if(shieldCanBlock && !(unblockable&WPNUNB_SHLD))
4340 {
4341 switch(the_defence)
4342 {
4343 case edIGNORE:
4344 return 0;
4345 case edIGNOREL1:
4346 case edSTUNORIGNORE:
4347 if(*power <= 0)
4348 return 0;
4349 }
4350 sfx(WAV_CHINK,pan(int32_t(x)));
4351 return 1;
4352 }
4353
4354 607 int32_t new_id = id;
4355 607 int32_t effect_type = dmisc15;
4356 607 int32_t delay_timer = 90;
4357 607 enemy *gleeok = NULL;
4358 607 enemy *ptra = NULL;
4359 607 int32_t c = 0;
4360
4361
1/29
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 607 times.
607 switch(the_defence)
4362 {
4363 case edREPLACE:
4364 {
4365 sclk = 0;
4366 if ( dmisc16 > 0 ) new_id = dmisc16;
4367 else new_id = id+1;
4368 if ( new_id > 511 ) new_id = id; //Sanity bound to legal enemy IDs.
4369 if ( dmisc17 > 0 ) delay_timer = dmisc17;
4370 //if ( dmisc18 > 0 ) dummy_wpn_id = dmisc18;
4371
4372 //Z_scripterrlog("new id is %d\n", new_id);
4373 switch(guysbuf[new_id&0xFFF].family)
4374 {
4375 //Fixme: possible enemy memory leak. (minor)
4376 case eeWALK:
4377 {
4378 enemy *e = new eStalfos(x,y,new_id,clk);
4379 guys.add(e);
4380 }
4381 break;
4382
4383 case eeLEV:
4384 {
4385 enemy *e = new eLeever(x,y,new_id,clk);
4386 guys.add(e);
4387 }
4388 break;
4389
4390 case eeTEK:
4391 {
4392 enemy *e = new eTektite(x,y,new_id,clk);
4393 guys.add(e);
4394 }
4395 break;
4396
4397 case eePEAHAT:
4398 {
4399 enemy *e = new ePeahat(x,y,new_id,clk);
4400 guys.add(e);
4401 }
4402 break;
4403
4404 case eeZORA:
4405 {
4406 enemy *e = new eZora(x,y,new_id,clk);
4407 guys.add(e);
4408 }
4409 break;
4410
4411 case eeGHINI:
4412 {
4413 enemy *e = new eGhini(x,y,new_id,clk);
4414 guys.add(e);
4415 }
4416 break;
4417
4418 case eeKEESE:
4419 {
4420 enemy *e = new eKeese(x,y,new_id,clk);
4421 guys.add(e);
4422 }
4423 break;
4424
4425 case eeWIZZ:
4426 {
4427 enemy *e = new eWizzrobe(x,y,new_id,clk);
4428 guys.add(e);
4429 }
4430 break;
4431
4432 case eePROJECTILE:
4433 {
4434 enemy *e = new eProjectile(x,y,new_id,clk);
4435 guys.add(e);
4436 }
4437 break;
4438
4439 case eeWALLM:
4440 {
4441 enemy *e = new eWallM(x,y,new_id,clk);
4442 guys.add(e);
4443 }
4444 break;
4445
4446 case eeAQUA:
4447 {
4448 enemy *e = new eAquamentus(x,y,new_id,clk);
4449 guys.add(e);
4450 e->x = x;
4451 e->y = y;
4452 }
4453 break;
4454
4455 case eeMOLD:
4456 {
4457 enemy *e = new eMoldorm(x,y,new_id,zc_max(1,zc_min(254,guysbuf[new_id&0xFFF].misc1)));
4458 guys.add(e);
4459 e->x = x;
4460 e->y = y;
4461 }
4462 break;
4463
4464 case eeMANHAN:
4465 {
4466 enemy *e = new eManhandla(x,y,new_id,clk);
4467 guys.add(e);
4468 e->x = x;
4469 e->y = y;
4470 }
4471 break;
4472
4473 case eeGLEEOK:
4474 {
4475 *power = 0;
4476 gleeok = new eGleeok(x,y,new_id,guysbuf[new_id&0xFFF].misc1);
4477 guys.add(gleeok);
4478 ((enemy*)guys.spr(guys.Count()-1))->hclk = delay_timer;
4479 //((enemy*)guys.spr(guys.Count()-1))->stunclk = delay_timer;
4480 new_id &= 0xFFF;
4481 int32_t head_cnt = zc_max(1,zc_min(254,guysbuf[new_id&0xFFF].misc1));
4482 Z_scripterrlog("Gleeok head count is %d\n",head_cnt);
4483 for(int32_t i=0; i<head_cnt; i++)
4484 {
4485 //enemy *e = new esGleeok(x,y,new_id+0x1000,clk,gleeok);
4486 if(!guys.add(new esGleeok((zfix)x,(zfix)y,new_id+0x1000,c, gleeok)))
4487 {
4488 al_trace("Gleeok head %d could not be created!\n",i+1);
4489
4490 for(int32_t j=0; j<i+1; j++)
4491 {
4492 guys.del(guys.Count()-1);
4493 }
4494
4495 break;
4496 }
4497 else
4498 {
4499 ((enemy*)guys.spr(guys.Count()-1))->hclk = delay_timer;
4500 //((enemy*)guys.spr(guys.Count()-1))->stunclk = delay_timer;
4501 }
4502
4503 c-=guysbuf[new_id].misc4;
4504 //gleeok->x = x;
4505 //gleeok->y = y;
4506 //gleeok = e;
4507 }
4508 return 1;
4509 }
4510
4511 case eeGHOMA:
4512 {
4513 enemy *e = new eGohma(x,y,new_id,clk);
4514 guys.add(e);
4515 e->x = x;
4516 e->y = y;
4517 }
4518 break;
4519
4520 case eeLANM:
4521 {
4522 enemy *e = new eLanmola(x,y,new_id,zc_max(1,zc_min(253,guysbuf[new_id&0xFFF].misc1)));
4523 guys.add(e);
4524 e->x = x;
4525 e->y = y;
4526 }
4527 break;
4528
4529 case eeGANON:
4530 {
4531 enemy *e = new eGanon(x,y,new_id,clk);
4532 guys.add(e);
4533 e->x = x;
4534 e->y = y;
4535 }
4536 break;
4537
4538 case eeFAIRY:
4539 {
4540 enemy *e = new eItemFairy(x,y,new_id+0x1000*clk,clk);
4541 guys.add(e);
4542 e->x = x;
4543 e->y = y;
4544 }
4545 break;
4546
4547 case eeFIRE:
4548 {
4549 enemy *e = new eFire(x,y,new_id,clk);
4550 guys.add(e);
4551 e->x = x;
4552 e->y = y;
4553 }
4554 break;
4555
4556 case eeOTHER:
4557 {
4558 enemy *e = new eOther(x,y,new_id,clk);
4559 guys.add(e);
4560 e->x = x;
4561 e->y = y;
4562 }
4563 break;
4564
4565 case eeSPINTILE:
4566 {
4567 enemy *e = new eSpinTile(x,y,new_id,clk);
4568 guys.add(e);
4569 e->x = x;
4570 e->y = y;
4571 }
4572 break;
4573
4574 // and these enemies use the misc10/misc2 value
4575 case eeROCK:
4576 {
4577 switch(guysbuf[new_id&0xFFF].misc10)
4578 {
4579 case 1:
4580 {
4581 enemy *e = new eBoulder(x,y,new_id,clk);
4582 guys.add(e);
4583 e->x = x;
4584 e->y = y;
4585 }
4586 break;
4587
4588 case 0:
4589 default:
4590 {
4591 enemy *e = new eRock(x,y,new_id,clk);
4592 guys.add(e);
4593 e->x = x;
4594 e->y = y;
4595 }
4596 break;
4597 }
4598
4599 break;
4600 }
4601
4602 case eeTRAP:
4603 {
4604 switch(guysbuf[new_id&0xFFF].misc2)
4605 {
4606 case 1:
4607 {
4608 enemy *e = new eTrap2(x,y,new_id,clk);
4609 guys.add(e);
4610 e->x = x;
4611 e->y = y;
4612 }
4613 break;
4614
4615 case 0:
4616 default:
4617 {
4618 enemy *e = new eTrap(x,y,new_id,clk);
4619 guys.add(e);
4620 e->x = x;
4621 e->y = y;
4622 }
4623 break;
4624 }
4625
4626 break;
4627 }
4628
4629 case eeDONGO:
4630 {
4631 switch(guysbuf[new_id&0xFFF].misc10)
4632 {
4633 case 1:
4634 {
4635 enemy *e = new eDodongo2(x,y,new_id,clk);
4636 guys.add(e);
4637 e->x = x;
4638 e->y = y;
4639 }
4640 break;
4641
4642 case 0:
4643 default:
4644 {
4645 enemy *e = new eDodongo(x,y,new_id,clk);
4646 guys.add(e);
4647 e->x = x;
4648 e->y = y;
4649 }
4650 break;
4651 }
4652
4653 break;
4654 }
4655
4656 case eeDIG:
4657 {
4658 switch(guysbuf[new_id&0xFFF].misc10)
4659 {
4660 case 1:
4661 {
4662 enemy *e = new eLilDig(x,y,new_id,clk);
4663 guys.add(e);
4664 e->x = x;
4665 e->y = y;
4666 }
4667 break;
4668
4669 case 0:
4670 default:
4671 {
4672 enemy *e = new eBigDig(x,y,new_id,clk);
4673 guys.add(e);
4674 e->x = x;
4675 e->y = y;
4676 }
4677 break;
4678 }
4679
4680 break;
4681 }
4682
4683 case eePATRA:
4684 {
4685 switch(guysbuf[new_id&0xFFF].misc10)
4686 {
4687 case 1:
4688 {
4689 if (get_bit(quest_rules,qr_HARDCODED_BS_PATRA))
4690 {
4691 enemy *e = new ePatraBS(x,y,new_id,clk);
4692 guys.add(e);
4693 e->x = x;
4694 e->y = y;
4695 break;
4696 }
4697 }
4698 [[fallthrough]];
4699 case 0:
4700 default:
4701 {
4702 enemy *e = new ePatra(x,y,new_id,clk);
4703 guys.add(e);
4704 e->x = x;
4705 e->y = y;
4706 }
4707 break;
4708 }
4709
4710 break;
4711 }
4712
4713 case eeGUY:
4714 {
4715 switch(guysbuf[new_id&0xFFF].misc10)
4716 {
4717 case 1:
4718 {
4719 enemy *e = new eTrigger(x,y,new_id,clk);
4720 guys.add(e);
4721 }
4722 break;
4723
4724 case 0:
4725 default:
4726 {
4727 enemy *e = new eNPC(x,y,new_id,clk);
4728 guys.add(e);
4729 }
4730 break;
4731 }
4732
4733 break;
4734 }
4735
4736 case eeSCRIPT01:
4737 case eeSCRIPT02:
4738 case eeSCRIPT03:
4739 case eeSCRIPT04:
4740 case eeSCRIPT05:
4741 case eeSCRIPT06:
4742 case eeSCRIPT07:
4743 case eeSCRIPT08:
4744 case eeSCRIPT09:
4745 case eeSCRIPT10:
4746 case eeSCRIPT11:
4747 case eeSCRIPT12:
4748 case eeSCRIPT13:
4749 case eeSCRIPT14:
4750 case eeSCRIPT15:
4751 case eeSCRIPT16:
4752 case eeSCRIPT17:
4753 case eeSCRIPT18:
4754 case eeSCRIPT19:
4755 case eeSCRIPT20:
4756 {
4757 enemy *e = new eScript(x,y,new_id,clk);
4758 guys.add(e);
4759 e->x = x;
4760 e->y = y;
4761 break;
4762 }
4763
4764
4765 case eeFFRIENDLY01:
4766 case eeFFRIENDLY02:
4767 case eeFFRIENDLY03:
4768 case eeFFRIENDLY04:
4769 case eeFFRIENDLY05:
4770 case eeFFRIENDLY06:
4771 case eeFFRIENDLY07:
4772 case eeFFRIENDLY08:
4773 case eeFFRIENDLY09:
4774 case eeFFRIENDLY10:
4775 {
4776 enemy *e = new eFriendly(x,y,new_id,clk);
4777 guys.add(e);
4778 e->x = x;
4779 e->y = y;
4780 break;
4781 }
4782
4783
4784 default: break;
4785 }
4786
4787 // add segments of segmented enemies
4788 int32_t c=0;
4789
4790 switch(guysbuf[new_id&0xFFF].family)
4791 {
4792 case eeMOLD:
4793 {
4794 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
4795 new_id &= 0xFFF;
4796
4797 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[new_id].misc1)); i++)
4798 {
4799 //christ this is messy -DD
4800 int32_t segclk = -i*((int32_t)(8.0/(zslongToFix(guysbuf[new_id&0xFFF].step*100))));
4801
4802 if(!guys.add(new esMoldorm((zfix)x,(zfix)y,new_id+0x1000,segclk)))
4803 {
4804 al_trace("Moldorm segment %d could not be created!\n",i+1);
4805
4806 for(int32_t j=0; j<i+1; j++)
4807 guys.del(guys.Count()-1);
4808
4809 return 0;
4810 }
4811
4812 if(i>0)
4813 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
4814
4815
4816 }
4817
4818 break;
4819 }
4820
4821 case eeLANM:
4822 {
4823 new_id &= 0xFFF;
4824 int32_t shft = guysbuf[new_id].misc2;
4825 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
4826 enemy *e = new esLanmola((zfix)x,(zfix)y,new_id+0x1000,0);
4827
4828 if(!guys.add(e))
4829 {
4830 al_trace("Lanmola segment 1 could not be created!\n");
4831 guys.del(guys.Count()-1);
4832 return 0;
4833 }
4834 e->x = x;
4835 e->y = y;
4836
4837
4838
4839 for(int32_t i=1; i<zc_max(1,zc_min(253,guysbuf[new_id&0xFFF].misc1)); i++)
4840 {
4841 enemy *e2 = new esLanmola((zfix)x,(zfix)y,new_id+0x2000,-(i<<shft));
4842 if(!guys.add(e2))
4843 {
4844 al_trace("Lanmola segment %d could not be created!\n",i+1);
4845
4846 for(int32_t j=0; j<i+1; j++)
4847 guys.del(guys.Count()-1);
4848
4849 return 0;
4850 }
4851 e2->x = x;
4852 e2->y = y;
4853
4854 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
4855
4856 }
4857 }
4858 break;
4859
4860 case eeMANHAN:
4861 new_id &= 0xFFF;
4862
4863 for(int32_t i=0; i<((!(guysbuf[new_id].misc2))?4:8); i++)
4864 {
4865 if(!guys.add(new esManhandla((zfix)x,(zfix)y,new_id+0x1000,i)))
4866 {
4867 al_trace("Manhandla head %d could not be created!\n",i+1);
4868
4869 for(int32_t j=0; j<i+1; j++)
4870 {
4871 guys.del(guys.Count()-1);
4872 }
4873
4874 return 0;
4875 }
4876
4877
4878 ((enemy*)guys.spr(guys.Count()-1))->frate=guysbuf[new_id].misc1;
4879 }
4880
4881 break;
4882
4883 case eeGLEEOK:
4884 {
4885 /*
4886 new_id &= 0xFFF;
4887 int32_t head_cnt = zc_max(1,zc_min(254,guysbuf[new_id&0xFFF].misc1));
4888 Z_scripterrlog("Gleeok head count is %d\n",head_cnt);
4889 for(int32_t i=0; i<head_cnt; i++)
4890 {
4891 //enemy *e = new esGleeok(x,y,new_id+0x1000,clk,gleeok);
4892 if(!guys.add(new esGleeok((zfix)x,(zfix)y,new_id+0x1000,c, gleeok)))
4893 {
4894 al_trace("Gleeok head %d could not be created!\n",i+1);
4895
4896 for(int32_t j=0; j<i+1; j++)
4897 {
4898 guys.del(guys.Count()-1);
4899 }
4900
4901 break;
4902 }
4903
4904 c-=guysbuf[new_id].misc4;
4905 */
4906
4907 // }
4908 }
4909 break;
4910
4911
4912 case eePATRA:
4913 {
4914 new_id &= 0xFFF;
4915 int32_t outeyes = 0;
4916 ptra = new ePatraBS((zfix)x,(zfix)y,id,clk);
4917
4918 for(int32_t i=0; i<zc_min(254,guysbuf[new_id&0xFFF].misc1); i++)
4919 {
4920 if(!((guysbuf[new_id].misc10&&get_bit(quest_rules,qr_HARDCODED_BS_PATRA))?guys.add(new esPatraBS((zfix)x,(zfix)y,new_id+0x1000,i,ptra)):guys.add(new esPatra((zfix)x,(zfix)y,new_id+0x1000,i,ptra))))
4921 {
4922 al_trace("Patra outer eye %d could not be created!\n",i+1);
4923
4924 for(int32_t j=0; j<i+1; j++)
4925 guys.del(guys.Count()-1);
4926
4927 return 0;
4928 }
4929 else
4930 outeyes++;
4931
4932
4933 }
4934
4935 for(int32_t i=0; i<zc_min(254,guysbuf[new_id&0xFFF].misc2); i++)
4936 {
4937 if(!guys.add(new esPatra((zfix)x,(zfix)y,new_id+0x1000,i,ptra)))
4938 {
4939 al_trace("Patra inner eye %d could not be created!\n",i+1);
4940
4941 for(int32_t j=0; j<i+1+zc_min(254,outeyes); j++)
4942 guys.del(guys.Count()-1);
4943
4944 return 0;
4945 }
4946
4947
4948 }
4949 delete ptra;
4950 break;
4951 }
4952 }
4953
4954
4955
4956 ((enemy*)guys.spr(guys.Count()-1))->count_enemy = true;
4957 ((enemy*)guys.spr(guys.Count()-1))->stunclk = delay_timer;
4958 ((enemy*)guys.spr(guys.Count()-1))->dir = this->dir;
4959 ((enemy*)guys.spr(guys.Count()-1))->scale = this->scale;
4960 ((enemy*)guys.spr(guys.Count()-1))->angular = this->angular;
4961 ((enemy*)guys.spr(guys.Count()-1))->angle = this->angle;
4962 ((enemy*)guys.spr(guys.Count()-1))->rotation = this->rotation;
4963 //((enemy*)guys.spr(guys.Count()-1))->mainguy = this->mainguy; //This might mean that it is a core.
4964 ((enemy*)guys.spr(guys.Count()-1))->itemguy = this->itemguy;
4965 ((enemy*)guys.spr(guys.Count()-1))->leader = this->leader;
4966 ((enemy*)guys.spr(guys.Count()-1))->hclk = delay_timer;
4967 ((enemy*)guys.spr(guys.Count()-1))->script_spawned = this->script_spawned;
4968 ((enemy*)guys.spr(guys.Count()-1))->script_UID = this->script_UID;
4969 ((enemy*)guys.spr(guys.Count()-1))->sclk = 0;
4970
4971
4972 item_set = 0; //Do not make a drop.
4973
4974 switch(effect_type)
4975 {
4976 case -7:
4977 {
4978 weapon *w = new weapon(x,y-fakez,z,wBomb,0,wdp,0,-1,getUID(),false, 0);
4979 Lwpns.add(w);
4980 break;
4981 }
4982 case -6:
4983 {
4984 weapon *w = new weapon(x,y-fakez,z,wSBomb,0,wdp,0,-1,getUID(),false, 0);
4985 Lwpns.add(w);
4986 break;
4987 }
4988 case -5:
4989 {
4990 weapon *w = new weapon(x,y-fakez,z,wBomb,effect_type,0,0,Hero.getUID(), txsz, tysz);
4991 Lwpns.add(w);
4992 break;
4993 }
4994 case -4:
4995 {
4996 weapon *w = new weapon(x,y-fakez,z,wSBomb,effect_type,0,0,Hero.getUID(), txsz, tysz);
4997 Lwpns.add(w);
4998 break;
4999 }
5000 case -3: explode(1); break;
5001 case -2: explode(2); break;
5002 case -1: explode(0); break;
5003 case 0: break;
5004
5005 default:
5006 {
5007 //Dummy weapon function
5008 if ( effect_type > 255 ) effect_type = 0; //Sanity bound the sprite ID.
5009 weapon *w = new weapon(x,y-fakez,z,wSSparkle,effect_type,0,0,Hero.getUID(), txsz, tysz,0,0,0,0,0,0,0);
5010 Lwpns.add(w);
5011 break;
5012 }
5013 }
5014
5015
5016 yofs = -32768;
5017 switch(guysbuf[new_id&0xFFF].family)
5018 {
5019 case eeGLEEOK:
5020 {
5021 Z_scripterrlog("Replacing a gleeok.\n");
5022 enemy *tempenemy = (enemy *) guys.getByUID(parentCore);
5023 hp = -999;
5024 tempenemy->hp = -999;
5025 break;
5026
5027 }
5028 default:
5029 hp = -1000; break;
5030 }
5031 ++game->guys[(currmap*MAPSCRSNORMAL)+currscr];
5032 return 1;
5033
5034 }
5035 case edSPLIT:
5036 {
5037 //int32_t ex = x; int32_t ey = y;
5038 //al_trace("edSplit dmisc3: %d\n", dmisc3);
5039 //al_trace("edSplit dmisc4: %d\n", dmisc4);
5040 /*
5041 if ( txsx > 1 )
5042 {
5043 ex += ( txsz-1 ) * 8; //from its middle
5044 }
5045 if ( tysx > 1 )
5046 {
5047 ey += ( tysz-1 ) * 8; //from its middle
5048 }
5049 */
5050 for ( int32_t q = 0; q < dmisc4; q++ )
5051 {
5052
5053 //addenemy((x+(txsz*16)/2),(y+(tysz*16)/2),dmisc3+0x1000,-15);
5054 addenemy(
5055 //ex,ey,
5056 x,y,
5057 dmisc3+0x1000,-15);
5058 //addenemy(ex,ey,dmisc3,0);
5059
5060 }
5061 item_set = 0; //Do not make a drop.
5062 hp = -1000;
5063 return -1;
5064
5065 }
5066 case edSUMMON:
5067 {
5068
5069
5070 //al_trace("edSplit dmisc3: %d\n", dmisc3);
5071 //al_trace("edSplit dmisc4: %d\n", dmisc4);
5072 int32_t summon_count = (zc_oldrand()%dmisc4)+1;
5073 for ( int32_t q = 0; q < summon_count; q++ )
5074 {
5075 int32_t x2=16*((zc_oldrand()%12)+2);
5076 int32_t y2=16*((zc_oldrand()%7)+2);
5077 addenemy(
5078 //(x+(txsz*16)/2),(y+(tysz*16)/2)
5079 x2,y2,
5080 dmisc3+0x1000,-15);
5081 //addenemy(ex,ey,dmisc3,0);
5082
5083 }
5084 sfx(get_bit(quest_rules,qr_MORESOUNDS) ? WAV_ZN1SUMMON : WAV_FIRE,pan(int32_t(x)));
5085 return -1;
5086
5087 }
5088
5089 case edEXPLODESMALL:
5090 {
5091 weapon *ew=new weapon(x,y-fakez,z, ewBomb, 0, dmisc4, dir,-1,getUID(),false);
5092 Ewpns.add(ew);
5093 item_set = 0; //Should we make a drop?
5094 hp = -1000;
5095 return -1;
5096 }
5097
5098
5099 case edEXPLODEHARMLESS:
5100 {
5101 weapon *ew=new weapon(x,y-fakez,z, ewSBomb, 0, dmisc4, dir,-1,getUID(),false);
5102 Ewpns.add(ew);
5103 ew->hyofs = -32768;
5104 item_set = 0; //Should we make a drop?
5105 hp = -1000;
5106 return -1;
5107 }
5108
5109
5110 case edEXPLODELARGE:
5111 {
5112 weapon *ew=new weapon(x,y-fakez,z, ewSBomb, 0, dmisc4, dir,-1,getUID(),false);
5113 Ewpns.add(ew);
5114
5115 hp = -1000;
5116 return -1;
5117 }
5118
5119
5120 case edTRIGGERSECRETS:
5121 {
5122 hidden_entrance(0, true, false, -4);
5123 return -1;
5124 }
5125
5126 case edSTUNORCHINK:
5127 if (stunclk && get_bit(quest_rules, qr_NO_STUNLOCK))
5128 {
5129 sfx(WAV_CHINK,pan(int32_t(x)));
5130 return 1;
5131 }
5132 else if(*power <= 0)
5133 {
5134 //al_trace("defendNew() is at: %s\n", "returning edSTUNORCHINK");
5135 sfx(WAV_CHINK,pan(int32_t(x)));
5136 return 1;
5137 }
5138 [[fallthrough]];
5139
5140 case edSTUNORIGNORE:
5141 if (stunclk && get_bit(quest_rules, qr_NO_STUNLOCK))
5142 {
5143 sfx(WAV_CHINK,pan(int32_t(x)));
5144 return 1;
5145 }
5146 else if(*power <= 0)
5147 return 0;
5148 [[fallthrough]];
5149
5150 case edSTUNONLY:
5151 if((wpnId==wFire || wpnId==wBomb || wpnId==wSBomb || wpnId==wHookshot || wpnId==wSword) && stunclk>=159)
5152 {
5153 //al_trace("enemy::defend(), edSTUNONLY found a weapon of type FIRE, BOMB, SBOMB, HOOKSHOT, or SWORD:, with wpnId: \n", wpnId);
5154 // Z_message("enemy::defend(), edSTUNONLY found a weapon of type FIRE, BOMB, SBOMB, HOOKSHOT, or SWORD:, with wpnId: \n", wpnId);
5155 return 1;
5156 }
5157 if (stunclk && get_bit(quest_rules, qr_NO_STUNLOCK))
5158 {
5159 sfx(WAV_CHINK,pan(int32_t(x)));
5160 return 1;
5161 }
5162 else
5163 {
5164 stunclk=160;
5165 sfx(WAV_EHIT,pan(int32_t(x)));
5166
5167 return 1;
5168 }
5169
5170 case edCHINKL1:
5171 if(*power >= 1*game->get_hero_dmgmult()) break;
5172 [[fallthrough]];
5173 case edCHINKL2:
5174 if(*power >= 2*game->get_hero_dmgmult()) break;
5175 [[fallthrough]];
5176 case edCHINKL4:
5177 if(*power >= 4*game->get_hero_dmgmult()) break;
5178 [[fallthrough]];
5179 case edCHINKL6:
5180 if(*power >= 6*game->get_hero_dmgmult()) break;
5181 [[fallthrough]];
5182 case edCHINKL8:
5183 if(*power >= 8*game->get_hero_dmgmult()) break;
5184 [[fallthrough]];
5185 case edCHINKL10:
5186 if(*power >= 10*game->get_hero_dmgmult()) break;
5187 [[fallthrough]];
5188 case edCHINK:
5189 //al_trace("defendNew() is at: %s\n", "returning edCHINK");
5190 sfx(WAV_CHINK,pan(int32_t(x)));
5191 return 1;
5192
5193 case edIGNOREL1:
5194 if(*power > 0) break;
5195 [[fallthrough]];
5196
5197 case edIGNORE:
5198 return 0;
5199
5200 case ed1HKO:
5201 *power = hp;
5202 return -2;
5203
5204 case ed2x:
5205 {
5206 *power = zc_max(1,*power*2);
5207 //int32_t pow = *power;
5208 //*power = vbound((pow*2),0,214747);
5209 return -1;
5210 }
5211 case ed3x:
5212 {
5213 *power = zc_max(1,*power*3);
5214 //int32_t pow = *power;
5215 //*power = vbound((pow*3),0,214747);
5216 return -1;
5217 }
5218
5219 case ed4x:
5220 {
5221 *power = zc_max(1,*power*4);
5222 //int32_t pow = *power;
5223 //*power = vbound((pow*4),0,214747);
5224 return -1;
5225 }
5226
5227
5228 case edHEAL:
5229 { //Probably needs its own function, or routine in the damage functuon to heal if power is negative.
5230 //int32_t pow = *power;
5231 //*power = vbound((pow*-1),0,214747);
5232 //break;
5233 *power = zc_min(0,*power*-1);
5234 return -1;
5235 }
5236 /*
5237 case edLEVELDAMAGE:
5238 {
5239 int32_t pow = *power;
5240 int32_t lvl = *level;
5241 *power = vbound((pow*lvl),0,214747);
5242 break;
5243 }
5244 case edLEVELREDUCTION:
5245 {
5246 int32_t pow = *power;
5247 int32_t lvl = *level;
5248 *power = vbound((pow/lvl),0,214747);
5249 break;
5250 }
5251 */
5252
5253 case edQUARTDAMAGE:
5254 *power = zc_max(1,*power/2);
5255
5256 [[fallthrough]];
5257 case edHALFDAMAGE:
5258 *power = zc_max(1,*power/2);
5259 break;
5260
5261 case edSWITCH:
5262 {
5263 if(Hero.switchhookclk) return 0; //Already switching!
5264 switch(family)
5265 {
5266 case eeAQUA: case eeMOLD: case eeDONGO: case eeMANHAN: case eeGLEEOK:
5267 case eeDIG: case eeGHOMA: case eeLANM: case eePATRA: case eeGANON:
5268 return 0;
5269 }
5270 hooked_combopos = -1;
5271 hooked_layerbits = 0;
5272 switching_object = this;
5273 switch_hooked = true;
5274 Hero.doSwitchHook(game->get_switchhookstyle());
5275 if(QMisc.miscsfx[sfxSWITCHED])
5276 sfx(QMisc.miscsfx[sfxSWITCHED],int32_t(x));
5277 return 1;
5278 }
5279
5280 case 0:
5281 {
5282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 if(edef == edefSwitchHook)
5283 return -1;
5284
3/6
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 348 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 259 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
607 if (stunclk && get_bit(quest_rules, qr_NO_STUNLOCK) && *power == 0)
5285 {
5286 sfx(WAV_CHINK,pan(int32_t(x)));
5287 return 1;
5288 }
5289
5290 }
5291 607 }
5292
5293 607 return -1;
5294 607 }
5295
5296 607 int32_t enemy::defendNewInt(int32_t wpnId, int32_t *power, int32_t edef, byte unblockable, weapon* w)
5297 {
5298 607 std::vector<int32_t> &ev = FFCore.eventData;
5299 607 ev.clear();
5300 607 ev.push_back(*power*10000);
5301 607 ev.push_back(edef*10000);
5302 607 ev.push_back(unblockable*10000);
5303 607 ev.push_back(wpnId*10000);
5304 607 ev.push_back(0);
5305 607 ev.push_back(getUID());
5306
1/2
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
607 ev.push_back(w?w->getUID():0);
5307
5308 607 throwGenScriptEvent(GENSCR_EVENT_ENEMY_HIT1);
5309 607 *power = ev[0]/10000;
5310 607 edef = ev[1]/10000;
5311 607 unblockable = byte(ev[2]/10000);
5312 607 wpnId = ev[3] / 10000;
5313 607 bool nullify = ev[4]!=0;
5314 607 ev.clear();
5315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 if(nullify) return 0;
5316
5317 607 int32_t ret = defendNew(wpnId, power, edef, unblockable);
5318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 if(ret != -1) return ret;
5319 607 ev.push_back(*power*10000);
5320 607 ev.push_back(edef*10000);
5321 607 ev.push_back(unblockable*10000);
5322 607 ev.push_back(wpnId*10000);
5323 607 ev.push_back(0);
5324 607 ev.push_back(getUID());
5325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 ev.push_back(w?w->getUID():0);
5326
5327 607 throwGenScriptEvent(GENSCR_EVENT_ENEMY_HIT2);
5328 607 *power = ev[0]/10000;
5329 607 nullify = ev[4]!=0;
5330 607 ev.clear();
5331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 if(nullify) return 0;
5332 607 return -1;
5333 607 }
5334
5335 326 int32_t enemy::defenditemclassNew(int32_t wpnId, int32_t *power, weapon *w)
5336 {
5337 326 int32_t wid = getWeaponID(w);
5338
5339 326 int32_t edef = resolveEnemyDefence(w);
5340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 326 times.
326 if(QHeader.zelda_version > 0x250)
5341 return defendNewInt(wid, power, edef, w->unblockable, w);
5342
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 326 times.
✗ Branch 2 not taken.
326 switch(wid)
5343 {
5344 case wScript1: case wScript2: case wScript3: case wScript4: case wScript5:
5345 case wScript6: case wScript7: case wScript8: case wScript9: case wScript10:
5346 return defend(wpnId, power, edefSCRIPT);
5347
5348 case wWhistle:
5349 return -1;
5350
5351 default:
5352 326 return defendNewInt(wid, power, edef, w->unblockable, w);
5353 }
5354 326 }
5355
5356
5357 // Check defenses without actually acting on them.
5358 bool enemy::candamage(int32_t power, int32_t edef, byte unblockable)
5359 {
5360 switch(defense[edef])
5361 {
5362 case edSTUNONLY:
5363 return false;
5364 case edSTUNORCHINK:
5365 case edCHINK:
5366 return unblockable&WPNUNB_BLOCK;
5367 case edSTUNORIGNORE:
5368 case edIGNORE:
5369 return unblockable&WPNUNB_IGNR;
5370
5371 case edIGNOREL1:
5372 return (unblockable&WPNUNB_IGNR) || power >= 1*game->get_hero_dmgmult();
5373 case edCHINKL1:
5374 return (unblockable&WPNUNB_BLOCK) || power >= 1*game->get_hero_dmgmult();
5375
5376 case edCHINKL2:
5377 return (unblockable&WPNUNB_BLOCK) || power >= 2*game->get_hero_dmgmult();
5378
5379 case edCHINKL4:
5380 return (unblockable&WPNUNB_BLOCK) || power >= 4*game->get_hero_dmgmult();
5381
5382 case edCHINKL6:
5383 return (unblockable&WPNUNB_BLOCK) || power >= 6*game->get_hero_dmgmult();
5384
5385 case edCHINKL8:
5386 return (unblockable&WPNUNB_BLOCK) || power >= 8*game->get_hero_dmgmult();
5387 }
5388
5389 return true;
5390 }
5391
5392 // Do we do damage?
5393 // 0: takehit returns 0
5394 // 1: takehit returns 1
5395 // -1: do damage
5396 int32_t enemy::defend(int32_t wpnId, int32_t *power, int32_t edef)
5397 {
5398 if(shieldCanBlock)
5399 {
5400 switch(defense[edef])
5401 {
5402 case edIGNORE:
5403 return 0;
5404 case edIGNOREL1:
5405 case edSTUNORIGNORE:
5406 if(*power <= 0)
5407 return 0;
5408 }
5409
5410 sfx(WAV_CHINK,pan(int32_t(x)));
5411 return 1;
5412 }
5413
5414 switch(defense[edef])
5415 {
5416 case edSTUNORCHINK:
5417 if(*power <= 0)
5418 {
5419 sfx(WAV_CHINK,pan(int32_t(x)));
5420 return 1;
5421 }
5422
5423 [[fallthrough]];
5424 case edSTUNORIGNORE:
5425 if(*power <= 0)
5426 return 0;
5427
5428 [[fallthrough]];
5429 case edSTUNONLY:
5430 if((wpnId==wFire || wpnId==wBomb || wpnId==wSBomb || wpnId==wHookshot || wpnId==wSword) && stunclk>=159)
5431 return 1;
5432
5433 stunclk=160;
5434 sfx(WAV_EHIT,pan(int32_t(x)));
5435 return 1;
5436
5437 case edFREEZE:
5438 frozenclock=-1;
5439 //sfx(WAV_FREEZE,pan(int32_t(x)));
5440 return 1;
5441
5442 case edCHINKL1:
5443 if(*power >= 1*game->get_hero_dmgmult()) break;
5444 [[fallthrough]];
5445 case edCHINKL2:
5446 if(*power >= 2*game->get_hero_dmgmult()) break;
5447 [[fallthrough]];
5448 case edCHINKL4:
5449 if(*power >= 4*game->get_hero_dmgmult()) break;
5450 [[fallthrough]];
5451 case edCHINKL6:
5452 if(*power >= 6*game->get_hero_dmgmult()) break;
5453 [[fallthrough]];
5454 case edCHINKL8:
5455 if(*power >= 8*game->get_hero_dmgmult()) break;
5456 [[fallthrough]];
5457 case edCHINKL10:
5458 if(*power >= 10*game->get_hero_dmgmult()) break;
5459 [[fallthrough]];
5460 case edCHINK:
5461 sfx(WAV_CHINK,pan(int32_t(x)));
5462 return 1;
5463 case edTRIGGERSECRETS:
5464 hidden_entrance(0, true, false, -4);
5465 break;
5466
5467 case edIGNOREL1:
5468 if(*power > 0) break;
5469 [[fallthrough]];
5470 case edIGNORE:
5471 return 0;
5472
5473 case ed1HKO:
5474 *power = hp;
5475 return -2;
5476
5477 case ed2x:
5478 {
5479 *power = zc_max(1,*power*2);
5480 //int32_t pow = *power;
5481 //*power = vbound((pow*2),0,214747);
5482 return -1;
5483 }
5484 case ed3x:
5485 {
5486 *power = zc_max(1,*power*3);
5487 //int32_t pow = *power;
5488 //*power = vbound((pow*3),0,214747);
5489 return -1;
5490 }
5491
5492 case ed4x:
5493 {
5494 *power = zc_max(1,*power*4);
5495 //int32_t pow = *power;
5496 //*power = vbound((pow*4),0,214747);
5497 return -1;
5498 }
5499
5500
5501 case edHEAL:
5502 { //Probably needs its own function, or routine in the damage functuon to heal if power is negative.
5503 //int32_t pow = *power;
5504 //*power = vbound((pow*-1),0,214747);
5505 //break;
5506 *power = zc_min(0,*power*-1);
5507 return -1;
5508 }
5509 /*
5510 case edLEVELDAMAGE:
5511 {
5512 int32_t pow = *power;
5513 int32_t lvl = *level;
5514 *power = vbound((pow*lvl),0,214747);
5515 break;
5516 }
5517 case edLEVELREDUCTION:
5518 {
5519 int32_t pow = *power;
5520 int32_t lvl = *level;
5521 *power = vbound((pow/lvl),0,214747);
5522 break;
5523 }
5524 */
5525
5526
5527 case edQUARTDAMAGE:
5528 *power = zc_max(1,*power/2);
5529
5530 [[fallthrough]];
5531 case edHALFDAMAGE:
5532 *power = zc_max(1,*power/2);
5533 break;
5534 }
5535
5536 return -1;
5537 }
5538
5539 // Defend against a particular item class.
5540 int32_t enemy::defenditemclass(int32_t wpnId, int32_t *power)
5541 {
5542 int32_t def=-1;
5543
5544 switch(wpnId)
5545 {
5546 // These first 2 are only used by Gohma... enemy::takehit() has complicated stun-calculation code for these.
5547 case wBrang:
5548 def = defend(wpnId, power, edefBRANG);
5549 break;
5550
5551 case wHookshot:
5552 def = defend(wpnId, power, edefHOOKSHOT);
5553 break;
5554
5555 // Anyway...
5556 case wBomb:
5557 def = defend(wpnId, power, edefBOMB);
5558 break;
5559
5560 case wSBomb:
5561 def = defend(wpnId, power, edefSBOMB);
5562 break;
5563
5564 case wArrow:
5565 def = defend(wpnId, power, edefARROW);
5566 break;
5567
5568 case wFire:
5569 def = defend(wpnId, power, edefFIRE);
5570 break;
5571
5572 case wWand:
5573 def = defend(wpnId, power, edefWAND);
5574 break;
5575
5576 case wMagic:
5577 def = defend(wpnId, power, edefMAGIC);
5578 break;
5579
5580 case wHammer:
5581 def = defend(wpnId, power, edefHAMMER);
5582 break;
5583
5584 case wSword:
5585 def = defend(wpnId, power, edefSWORD);
5586 break;
5587
5588 case wBeam:
5589 def = defend(wpnId, power, edefBEAM);
5590 break;
5591
5592 case wRefBeam:
5593 def = defend(wpnId, power, edefREFBEAM);
5594 break;
5595
5596 case wRefMagic:
5597 def = defend(wpnId, power, edefREFMAGIC);
5598 break;
5599
5600 case wRefFireball:
5601 def = defend(wpnId, power, edefREFBALL);
5602 break;
5603
5604 case wRefRock:
5605 def = defend(wpnId, power, edefREFROCK);
5606 break;
5607
5608 case wStomp:
5609 def = defend(wpnId, power, edefSTOMP);
5610 break;
5611
5612 case wCByrna:
5613 def = defend(wpnId, power, edefBYRNA);
5614 break;
5615
5616 case wScript1:
5617 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT01);
5618 else def = defend(wpnId, power, edefSCRIPT);
5619 break;
5620
5621 case wScript2:
5622 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT02);
5623 else def = defend(wpnId, power, edefSCRIPT);
5624 break;
5625
5626 case wScript3:
5627 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT03);
5628 else def = defend(wpnId, power, edefSCRIPT);
5629 break;
5630
5631 case wScript4:
5632 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT04);
5633 else def = defend(wpnId, power, edefSCRIPT);
5634 break;
5635
5636 case wScript5:
5637 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT05);
5638 else def = defend(wpnId, power, edefSCRIPT);
5639 break;
5640
5641 case wScript6:
5642 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT06);
5643 else def = defend(wpnId, power, edefSCRIPT);
5644 break;
5645
5646 case wScript7:
5647 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT07);
5648 else def = defend(wpnId, power, edefSCRIPT);
5649 break;
5650
5651 case wScript8:
5652 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT08);
5653 else def = defend(wpnId, power, edefSCRIPT);
5654 break;
5655
5656 case wScript9:
5657 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT09);
5658 else def = defend(wpnId, power, edefSCRIPT);
5659 break;
5660
5661 case wScript10:
5662 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT10);
5663 else def = defend(wpnId, power, edefSCRIPT);
5664 break;
5665
5666 case wWhistle:
5667 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefWhistle);
5668 else break;
5669 break;
5670
5671
5672 //!ZoriaRPG : We need some special cases here, to ensure that old script defs don;t break.
5673 //Probably best to do this from the qest file, loading the values of Script(generic) into each
5674 //of the ten if the quest version is lower than N.
5675 //Either that, or we need a boolean flag to set int32_t he enemy editor, or by ZScript that changes this behaviour.
5676 //such as bool UseSeparatedScriptDefences. hah.
5677 default:
5678 //if(wpnId>=wScript1 && wpnId<=wScript10)
5679 // {
5680 // def = defend(wpnId, power, edefSCRIPT);
5681 // }
5682 // }
5683
5684 break;
5685 }
5686
5687 return def;
5688 }
5689
5690 // take damage or ignore it
5691 // -1: damage (if any) dealt
5692 // 1: blocked
5693 // 0: weapon passes through unhindered
5694 607 int32_t enemy::takehit(weapon *w)
5695 {
5696
2/4
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 607 times.
607 if(fallclk||drownclk) return 0;
5697 607 int32_t wpnId = w->id;
5698 //al_trace("takehit() wpnId is %d\n",wpnId);
5699 //if ( wpnId == wWhistle ) al_trace("Whistle weapon in %s\n", "takehit");
5700 607 int32_t power = w->power;
5701 607 int32_t wpnx = w->x;
5702 607 int32_t wpny = w->y;
5703 607 int32_t enemyHitWeapon = w->parentitem;
5704 int32_t wpnDir;
5705 607 int32_t parent_item = w->parentitem;
5706
5707 //if ( parent_item > -1 )
5708 //{
5709 // if ( itemsbuf[parent_item].useweapon > 0 /*&& wpnId != wWhistle*/ )
5710 // {
5711 // wpnId = itemsbuf[parent_item].useweapon;
5712 // }
5713
5714 //}
5715 //if ( parent_item == -1 && w->ScriptGenerated )
5716 //{
5717 // if ( w->useweapon > 0 /*&& wpnId != wWhistle*/ )
5718 // {
5719 // wpnId = w->useweapon;
5720 // }
5721
5722 //}
5723 //al_trace("takehit wpnId is: %d\n",wpnId);
5724
5725 //Shoud be set from idata from the weapon::weaon constructor. -Z
5726
1/2
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
607 if ( w->useweapon > 0 /*&& wpnId != wWhistle*/ )
5727 {
5728 wpnId = w->useweapon;
5729 }
5730
5731 //al_trace("takehit() useweapon is %d\n",itemsbuf[parent_item].useweapon);
5732
5733 //Weapon Editor -Z
5734
5735
5736 // If it's a boomerang that just bounced, use the opposite direction;
5737 // otherwise, it might bypass a shield. This probably won't handle
5738 // every case correctly, but it's better than having shields simply
5739 // not work against boomerangs.
5740
8/8
✓ Branch 0 taken 281 times.
✓ Branch 1 taken 326 times.
✓ Branch 2 taken 169 times.
✓ Branch 3 taken 112 times.
✓ Branch 4 taken 168 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 20 times.
✓ Branch 7 taken 148 times.
607 if(w->id==wBrang && w->misc==1 && w->clk2>=256 && w->clk2<264)
5741 148 wpnDir = oppositeDir[w->dir];
5742 else
5743 459 wpnDir = w->dir;
5744
5745
4/8
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 607 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 607 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 607 times.
607 if(dying || clk<0 || hclk>0 || superman)
5746 {
5747 return 0;
5748 }
5749
5750 //Prevent boomerang from writing to hitby[] for more than one frame.
5751 //This also prevents stunlock.
5752 //if ( stunclk > 0 ) return 0;
5753 //this needs a rule for boomerangs that cannot stunlock!
5754 //further, bouncing weapons should probably SFX_CHINK and bounce here.
5755 //sigh.
5756
5757 607 int32_t ret = -1;
5758
5759 // This obscure quest rule...
5760
4/6
✓ Branch 0 taken 426 times.
✓ Branch 1 taken 181 times.
✓ Branch 2 taken 426 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 426 times.
607 if(get_bit(quest_rules,qr_BOMBDARKNUTFIX) && (wpnId==wBomb || wpnId==wSBomb))
5761 {
5762 double _MSVC2022_tmp1, _MSVC2022_tmp2;
5763 double ddir=atan2_MSVC2022_FIX(double(wpny-y),double(x-wpnx));
5764 wpnDir=zc_oldrand()&3;
5765
5766 if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
5767 {
5768 wpnDir=down;
5769 }
5770 else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
5771 {
5772 wpnDir=right;
5773 }
5774 else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
5775 {
5776 wpnDir=up;
5777 }
5778 else
5779 {
5780 wpnDir=left;
5781 }
5782 }
5783
5784 607 int32_t xdir = dir;
5785 607 shieldCanBlock=false;
5786
5787 //if (family==eeFLOAT && flags&(inv_front|inv_back_inv_left|inv_right)) xdir=down;
5788
2/4
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 607 times.
607 if(!(w->unblockable&WPNUNB_BLOCK)&&((wpnId==wHookshot && hitshield(wpnx, wpny, xdir))
5789
7/10
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 607 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 607 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 607 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 607 times.
607 || ((flags&inv_front && wpnDir==(xdir^down)) || (flags&inv_back && wpnDir==(xdir^up)) || (flags&inv_left && wpnDir==(xdir^left)) || (flags&inv_right && wpnDir==(xdir^right))))
5790 )
5791 // The hammer should already be dealt with by subclasses (Walker etc.)
5792 {
5793
0/9
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
16 switch(wpnId)
5794 {
5795 // Weapons which shields protect against
5796 case wSword:
5797 case wWand:
5798 if(Hero.getCharging()>0)
5799 Hero.setAttackClk(Hero.getAttackClk()+1); //Cancel charging
5800
5801 [[fallthrough]];
5802 case wHookshot:
5803 case wHSHandle:
5804 case wBrang:
5805 shieldCanBlock=true;
5806 break;
5807
5808 case wBeam:
5809 case wRefBeam:
5810 // Mirror shielded enemies!
5811 #if 0
5812 if(false /*flags2&guy_mirror*/ && !get_bit(quest_rules,qr_SWORDMIRROR))
5813 {
5814 if(wpnId>wEnemyWeapons)
5815 return 0;
5816
5817 sfx(WAV_CHINK,pan(int32_t(x)));
5818 return 1;
5819 }
5820
5821 #endif
5822
5823 [[fallthrough]];
5824 case wRefRock:
5825 case wRefFireball:
5826 case wMagic:
5827 #if 0
5828 if(false /*flags2&guy_mirror*/ && (wpnId!=wRefRock || get_bit(quest_rules,qr_REFLECTROCKS)))
5829 {
5830 sfx(WAV_CHINK,pan(int32_t(x)));
5831 return 3;
5832 }
5833
5834 #endif
5835
5836 if(wpnId>wEnemyWeapons)
5837 return 0;
5838
5839 [[fallthrough]];
5840 default:
5841 shieldCanBlock=true;
5842 break;
5843
5844 // Bombs
5845 case wSBomb:
5846 case wBomb:
5847 if (!get_bit(quest_rules,qr_TRUEFIXEDBOMBSHIELD)) goto hitclock;
5848 else if (!get_bit(quest_rules,qr_BOMBSPIERCESHIELD))
5849 {
5850 sfx(WAV_CHINK,pan(int32_t(x)));
5851 return 0;
5852 }
5853 else break;
5854
5855 // Weapons which ignore shields
5856 case wWhistle:
5857 case wHammer:
5858 break;
5859
5860 // Weapons which shouldn't be removed by shields
5861 case wLitBomb:
5862 case wLitSBomb:
5863 case wWind:
5864 case wPhantom:
5865 case wSSparkle:
5866 case wBait:
5867 return 0;
5868
5869 [[fallthrough]];
5870 case wFire:
5871 #if 0
5872 if(false /*flags2&guy_mirror*/)
5873 {
5874 sfx(WAV_CHINK,pan(int32_t(x)));
5875 return 1;
5876 }
5877
5878 #endif
5879 ;
5880 }
5881 }
5882
5883
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 326 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 281 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
607 switch(wpnId)
5884 {
5885 case wWhistle: //No longer completely ignore whistle weapons! -Z
5886 {
5887
5888 if ( ((itemsbuf[parent_item].flags & ITEM_FLAG2) == 0) || ( parent_item == -1 ) ) //if the flag is set, or the weapon is scripted
5889 {
5890 //al_trace("Whistle weapon in %s\n", "takehit flag == 0");
5891 return 0; break;
5892 }
5893 else
5894 {
5895 w->power = power = itemsbuf[parent_item].misc5;
5896
5897 int32_t def = defendNewInt(wpnId, &power, resolveEnemyDefence(w), w->unblockable, w);
5898
5899 if(def <= 0)
5900 {
5901 if ( def == -2 ) hp -= hp;
5902 else hp -= power;
5903 return def;
5904 }
5905 break;
5906 }
5907 break;
5908 }
5909
5910 case wPhantom:
5911 return 0;
5912
5913 case wLitBomb:
5914 case wLitSBomb:
5915 case wBait:
5916 case wWind:
5917 case wSSparkle:
5918 return 0;
5919
5920 case wFSparkle:
5921
5922 // Only take sparkle damage if the sparkle's parent item is not
5923 // defended against.
5924 if(enemyHitWeapon > -1)
5925 {
5926 int32_t p = 0;
5927 int32_t f = itemsbuf[enemyHitWeapon].family;
5928
5929 switch(f)
5930 {
5931 case itype_arrow:
5932 if(!candamage(p, edefARROW, w->unblockable)) return 0;
5933
5934 break;
5935
5936 case itype_cbyrna:
5937 if(!candamage(p, edefBYRNA, w->unblockable)) return 0;
5938
5939 break;
5940
5941 case itype_brang:
5942 if(!candamage(p, edefBRANG, w->unblockable)) return 0;
5943
5944 break;
5945
5946 default:
5947 return 0;
5948 }
5949 }
5950
5951 wpnId = wSword;
5952 power = game->get_hero_dmgmult()>>1;
5953 goto fsparkle;
5954 break;
5955
5956 case wBrang:
5957 {
5958 //int32_t def = defendNew(wpnId, &power, edefBRANG, w);
5959 281 int32_t def = defendNewInt(wpnId, &power, resolveEnemyDefence(w), w->unblockable, w);
5960 //preventing stunlock might be best, here. -Z
5961
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 281 times.
281 if(def >= 0) return def;
5962
5963 // Not hurt by 0-damage weapons
5964
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 226 times.
281 if(!(flags & guy_bhit))
5965 {
5966 226 stunclk=160;
5967
5968
2/4
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 226 times.
226 if(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))
5969 {
5970 hp -= (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))*game->get_hero_dmgmult();
5971 goto hitclock;
5972 }
5973
5974 226 break;
5975 }
5976
5977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 if(!power)
5978
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 hp-=(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].fam_type : current_item(itype_brang))*game->get_hero_dmgmult();
5979 else
5980 hp-=power;
5981
5982 55 goto hitclock;
5983 }
5984
5985 case wHookshot:
5986 {
5987 //int32_t def = defendNew(wpnId, &power, edefHOOKSHOT,w);
5988 int32_t def = defendNewInt(wpnId, &power, resolveEnemyDefence(w), w->unblockable, w);
5989
5990 if(def >= 0) return def;
5991
5992 bool swgrab = switch_hooked || w->family_class == itype_switchhook;
5993 if(swgrab || !(flags & guy_bhit))
5994 {
5995 if(!swgrab)
5996 stunclk=160;
5997
5998 if(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot))
5999 {
6000 hp -= (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot))*game->get_hero_dmgmult();
6001 goto hitclock;
6002 }
6003
6004 break;
6005 }
6006
6007 if(!power) hp-=(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].fam_type : current_item(itype_hookshot))*game->get_hero_dmgmult();
6008 else
6009 hp-=power;
6010
6011 goto hitclock;
6012 }
6013 break;
6014
6015 case wHSHandle:
6016 {
6017 if(itemsbuf[enemyHitWeapon>-1 ? enemyHitWeapon : current_item_id(itype_hookshot)].flags & ITEM_FLAG1)
6018 return 0;
6019
6020 bool ignorehookshot = ((defense[edefHOOKSHOT] == edIGNORE) || ((defense[edefHOOKSHOT] == edIGNOREL1 || defense[edefHOOKSHOT] == edSTUNORIGNORE)
6021 && (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot)) <= 0));
6022
6023 // Peahats, Darknuts, Aquamentuses, Pols Voices, Wizzrobes, Manhandlas
6024 if(!(family==eePEAHAT || family==eeAQUA || family==eeMANHAN || (family==eeWIZZ && !ignorehookshot)
6025 || (family==eeWALK && dmisc9==e9tPOLSVOICE) || (family==eeWALK && flags&(inv_back|inv_front|inv_left|inv_right))))
6026 return 0;
6027
6028 power = game->get_hero_dmgmult();
6029 }
6030
6031 fsparkle:
6032
6033 [[fallthrough]];
6034 default:
6035 // Work out the defenses!
6036 {
6037 326 int32_t def = defenditemclassNew(wpnId, &power, w);
6038
6039
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 326 times.
326 if(def >= 0)
6040 return def;
6041
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
326 else if(def == -2)
6042 {
6043 ret = 0;
6044 }
6045 }
6046
6047
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
652 if(!power)
6048 {
6049 if(flags & guy_bhit)
6050 hp-=1;
6051 else
6052 {
6053 // Don't make a long chain of 'stun' hits
6054 if((wpnId==wFire || wpnId==wBomb || wpnId==wSBomb || wpnId==wSword) && stunclk>0)
6055 return 1;
6056
6057
6058 if(!switch_hooked)
6059 stunclk=160;
6060 break;
6061 }
6062 }
6063 326 else hp-=power;
6064
6065 hitclock:
6066 381 hclk=33;
6067
6068 // Use w->dir instead of wpnDir to make sure boomerangs don't push enemies the wrong way
6069
2/2
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 225 times.
381 if((dir&2)==(w->dir&2))
6070 {
6071 225 sclk=(w->dir<<8)+16;
6072 225 }
6073 381 }
6074
6075
5/6
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 555 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 52 times.
607 if(((wpnId==wBrang) || (get_bit(quest_rules,qr_NOFLASHDEATH))) && (hp<=0 && !immortal))
6076 {
6077 52 fading=fade_blue_poof;
6078 52 }
6079
6080
6081 /*
6082 if( hitsfx > 0 ) //user set hit sound.
6083 {
6084 if ( !dying ) //Don't play the hit sound when dying.
6085 sfx(hitsfx, pan(int32_t(x)));
6086 }
6087 else sfx(WAV_EHIT, pan(int32_t(x))); //Don't play this one if the user sets a custom sound!
6088 */
6089 /*
6090 if( hitsfx > 0 ) //A sound is set.
6091 {
6092 if ( !dying ) //Don't play the hit sound when dying.
6093 sfx(hitsfx, pan(int32_t(x)));
6094 }
6095 */
6096
4/6
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 607 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 86 times.
✓ Branch 5 taken 521 times.
607 if ( FFCore.getQuestHeaderInfo(vZelda) > 0x250 || ( FFCore.getQuestHeaderInfo(vZelda) == 0x250 && FFCore.getQuestHeaderInfo(vBuild) > 31 )) //2.53 Gamma 2 and later
6097 {
6098
1/2
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
86 if( hitsfx > 0 ) //user-set hit sound.
6099 {
6100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86 times.
86 if (!dying) //don't play the hit sound on death! -Z
6101 86 sfx(hitsfx, pan(int32_t(x)));
6102 86 }
6103 else sfx(WAV_EHIT, pan(int32_t(x))); //Don't play the hardcoded sound if the user sets a custom one.
6104 86 }
6105 else //2.50.2 or earlier
6106 {
6107 521 sfx(WAV_EHIT, pan(int32_t(x)));
6108 521 sfx(hitsfx, pan(int32_t(x)));
6109 }
6110
2/2
✓ Branch 0 taken 606 times.
✓ Branch 1 taken 1 times.
607 if(family==eeGUY)
6111 1 sfx(WAV_EDEAD, pan(int32_t(x)));
6112
6113 // Penetrating weapons
6114
3/4
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 468 times.
✓ Branch 3 taken 139 times.
607 if((wpnId==wArrow || wpnId==wBeam) && !cannotpenetrate())
6115 {
6116 139 int32_t item=enemyHitWeapon;
6117
6118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139 times.
139 if(wpnId==wArrow)
6119 {
6120 //If we use an arrow type for the item's Weapon type, the flags differ, so we need to rely on the flags from an arrow class.
6121 if(item>=0 && (itemsbuf[item].flags&ITEM_FLAG1) && (itemsbuf[parent_item].family == itype_arrow))
6122 return 0;
6123 else if(get_bit(quest_rules,qr_ARROWS_ALWAYS_PENETRATE)) return 0;
6124 //if(item<0)
6125 else
6126 item=current_item_id(itype_arrow);
6127 }
6128
6129 else
6130 {
6131
6132 //If we use an swordbeam type for the item's Weapon type, the flags differ, so we need to rely on the flags from an arrow class.
6133
2/6
✓ Branch 0 taken 139 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 139 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
139 if(item>=0 && (itemsbuf[item].flags&ITEM_FLAG3) && (itemsbuf[parent_item].family == itype_sword))
6134 return 0;
6135
6136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139 times.
139 else if(get_bit(quest_rules,qr_SWORDBEAMS_ALWAYS_PENETRATE)) return 0;
6137 else
6138 //if(item<0)
6139 139 item=current_item_id(itype_sword);
6140 }
6141 139 }
6142
6143 607 return ret;
6144 607 }
6145
6146 206172 bool enemy::dont_draw()
6147 {
6148
3/6
✓ Branch 0 taken 206172 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 206172 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 206172 times.
206172 if(fading==fade_invisible || (((flags2&guy_blinking)||(fading==fade_flicker)) && (clk&1)))
6149 return true;
6150
6151
2/2
✓ Branch 0 taken 1500 times.
✓ Branch 1 taken 204672 times.
206172 if(flags&guy_invisible)
6152 1500 return true;
6153
6154
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 204672 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
204672 if(flags&lens_only && !lensclk)
6155 return true;
6156
6157
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 204672 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
204672 if(lensclk && (itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG6) && !(itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG7) &&
6158 !((flags&lens_only) && (get_bit(quest_rules,qr_LENSSEESENEMIES) || (itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG5))))
6159 return true;
6160
6161 204672 return false;
6162 206172 }
6163
6164 #define DRAW_NORMAL 2
6165 #define DRAW_CLOAKED 1
6166 #define DRAW_INVIS 0
6167 // base drawing function to be used by all derived classes instead of
6168 // sprite::draw()
6169 173970 void enemy::draw(BITMAP *dest)
6170 {
6171
3/6
✓ Branch 0 taken 173970 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 173970 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 173970 times.
173970 if(fading==fade_invisible || (((flags2&guy_blinking)||(fading==fade_flicker)) && (clk&1)))
6172 return;
6173
2/2
✓ Branch 0 taken 412 times.
✓ Branch 1 taken 173558 times.
173970 if(flags&guy_invisible)
6174 412 return;
6175
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 173558 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
173558 if(lensclk && (itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG6) && !(itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG7) && !(flags&lens_only))
6176 return;
6177
6178 //We did the normal don't_draw stuff here so we can make exceptions; specifically the lens check (which should make enemies
6179 // be cloaked if they have "invisible displays as cloaked" checked.
6180
6181 173558 byte canSee = DRAW_NORMAL;
6182 //Enemy specific stuff
6183
1/2
✓ Branch 0 taken 173558 times.
✗ Branch 1 not taken.
173558 if ( editorflags & ENEMY_FLAG1 )
6184 {
6185 canSee = DRAW_INVIS;
6186 if (editorflags & ENEMY_FLAG4) canSee = DRAW_CLOAKED;
6187 if (dmisc13 >= 0 && (editorflags & ENEMY_FLAG2))
6188 {
6189 if (game->item[dmisc13])
6190 {
6191 canSee = DRAW_NORMAL;
6192 }
6193 //else if ( lensclk && getlensid.flags SHOWINVIS )
6194 //{
6195 //
6196 //}
6197 //else
6198 //{
6199 // if ( (editorflags & ENEMY_FLAG4) ) canSee = DRAW_CLOAKED;
6200 // //otherwisem invisible
6201 //}
6202 }
6203 }
6204 //Room specific
6205
1/2
✓ Branch 0 taken 173558 times.
✗ Branch 1 not taken.
173558 if (tmpscr->flags3&fINVISROOM)
6206 {
6207 if (canSee == DRAW_NORMAL && !(current_item(itype_amulet)) &&
6208 !((itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG5) && lensclk) && family!=eeGANON) canSee = DRAW_CLOAKED;
6209 }
6210 //Lens check
6211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 173558 times.
173558 if (lensclk)
6212 {
6213 if((itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG6) && !(flags&lens_only))
6214 {
6215 if (canSee == DRAW_NORMAL)
6216 {
6217 if (itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG7) canSee = DRAW_CLOAKED;
6218 else canSee = DRAW_INVIS; //Should never happen cause dont_draw should catch this, but just in case.
6219 }
6220 }
6221 if(flags&lens_only)
6222 {
6223 if (canSee == DRAW_INVIS) canSee = DRAW_NORMAL;
6224 }
6225 }
6226 else
6227 {
6228
1/2
✓ Branch 0 taken 173558 times.
✗ Branch 1 not taken.
173558 if(flags&lens_only)
6229 canSee = DRAW_INVIS;
6230 }
6231
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 173558 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
173558 if (canSee == DRAW_INVIS && (editorflags & ENEMY_FLAG4)) canSee = DRAW_CLOAKED;
6232
2/4
✓ Branch 0 taken 173558 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 173558 times.
✗ Branch 3 not taken.
173558 if (canSee == DRAW_NORMAL && (editorflags & ENEMY_FLAG16)) canSee = DRAW_CLOAKED;
6233
6234
1/2
✓ Branch 0 taken 173558 times.
✗ Branch 1 not taken.
173558 if (canSee == DRAW_INVIS)
6235 return;
6236
6237
2/4
✓ Branch 0 taken 173558 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 173558 times.
173558 if(fallclk||drownclk)
6238 {
6239 if (canSee == DRAW_CLOAKED)
6240 {
6241 sprite::drawcloaked(dest);
6242 }
6243 else if (canSee == DRAW_NORMAL)
6244 {
6245 sprite::draw(dest);
6246 }
6247 return;
6248 }
6249 173558 int32_t cshold=cs;
6250
6251
2/2
✓ Branch 0 taken 6606 times.
✓ Branch 1 taken 166952 times.
173558 if(dying)
6252 {
6253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6606 times.
6606 if(clk2>=19)
6254 {
6255 if(!(clk2&2))
6256 {
6257 //if the enemy isn't totally invisible, or if it is, but Hero has the item needed to reveal it, draw it.
6258 if (canSee == DRAW_CLOAKED)
6259 {
6260 sprite::drawcloaked(dest);
6261 }
6262 else if (canSee == DRAW_NORMAL)
6263 {
6264 sprite::draw(dest);
6265 }
6266 }
6267 return;
6268 }
6269
6270 6606 flip = 0;
6271 6606 tile = wpnsbuf[spr_death].tile;
6272
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6606 times.
6606 if ( do_animation )
6273 {
6274 6606 int32_t offs = 0;
6275
1/2
✓ Branch 0 taken 6606 times.
✗ Branch 1 not taken.
6606 if(!get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS))
6276 {
6277 if(clk2 > 2)
6278 {
6279 spr_death_anim_clk=0;
6280 clk2=1;
6281 if(hp > -1000)
6282 death_sfx();
6283 }
6284 if(clk2==1 && spr_death_anim_clk>-1)
6285 {
6286 ++clk2;
6287 spr_death_anim_frm=(spr_death_anim_clk/zc_max(wpnsbuf[spr_death].speed,1));
6288 spr_death_anim_frm *= zc_max(1,txsz);
6289 int32_t rows = TILEROW(tile+spr_death_anim_frm)-TILEROW(tile);
6290 spr_death_anim_frm += TILES_PER_ROW*(zc_min(0,tysz-1)*rows);
6291 if(++spr_death_anim_clk >= (zc_max(wpnsbuf[spr_death].speed,1) * zc_max(wpnsbuf[spr_death].frames,1)))
6292 {
6293 spr_death_anim_clk=-1;
6294 clk2=1;
6295 }
6296 }
6297 tile += spr_death_anim_frm;
6298 }
6299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6606 times.
6606 else if(BSZ)
6300 {
6301 offs = zc_min((15-clk2)/3,4);
6302 }
6303
4/4
✓ Branch 0 taken 4234 times.
✓ Branch 1 taken 2372 times.
✓ Branch 2 taken 2122 times.
✓ Branch 3 taken 2112 times.
6606 else if(clk2>6 && clk2<=12)
6304 {
6305 2112 offs = 1;
6306 2112 }
6307
6308
2/2
✓ Branch 0 taken 4494 times.
✓ Branch 1 taken 2112 times.
6606 if(offs)
6309 {
6310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2112 times.
2112 offs *= zc_max(1,txsz);
6311 2112 int32_t rows = TILEROW(tile+offs)-TILEROW(tile);
6312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2112 times.
2112 offs += TILES_PER_ROW*(zc_min(0,tysz-1)*rows);
6313 2112 }
6314 6606 tile += offs;
6315 6606 }
6316
6317
4/6
✓ Branch 0 taken 6606 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6606 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2078 times.
✓ Branch 5 taken 4528 times.
6606 if(!get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS) || BSZ || fading==fade_blue_poof)
6318 2078 cs = wpnsbuf[spr_death].csets&15;
6319 else
6320 4528 cs = (((clk2+5)>>1)&3)+6;
6321 6606 }
6322
3/4
✓ Branch 0 taken 5335 times.
✓ Branch 1 taken 161617 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5335 times.
166952 else if(hclk>0 && getCanFlicker())
6323 {
6324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5335 times.
5335 if(family==eeGANON)
6325 cs=(((hclk-1)>>1)&3)+6;
6326
3/4
✓ Branch 0 taken 4830 times.
✓ Branch 1 taken 505 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4830 times.
5335 else if(hclk<33 && !get_bit(quest_rules,qr_ENEMIESFLICKER))
6327 4830 cs=(((hclk-1)>>1)&3)+6;
6328 5335 }
6329 //draw every other frame for flickering enemies
6330
8/10
✓ Branch 0 taken 86815 times.
✓ Branch 1 taken 86743 times.
✓ Branch 2 taken 86815 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5973 times.
✓ Branch 5 taken 80842 times.
✓ Branch 6 taken 172 times.
✓ Branch 7 taken 5801 times.
✓ Branch 8 taken 172 times.
✗ Branch 9 not taken.
173558 if((frame&1)==1 || !(family !=eeGANON && hclk>0 && get_bit(quest_rules,qr_ENEMIESFLICKER) && getCanFlicker()))
6331 {
6332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 173386 times.
173386 if (canSee == DRAW_CLOAKED)
6333 {
6334 sprite::drawcloaked(dest);
6335 }
6336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 173386 times.
173386 else if (canSee == DRAW_NORMAL)
6337 {
6338
1/2
✓ Branch 0 taken 173386 times.
✗ Branch 1 not taken.
173386 if ( frozenclock < 0 )
6339 {
6340 if ( frozentile > 0 ) tile = frozentile;
6341 loadpalset(csBOSS,frozencset);
6342 }
6343 173386 sprite::draw(dest);
6344 173386 }
6345 173386 }
6346 173558 cs=cshold;
6347 173970 }
6348
6349 //old zc bosses
6350 165500 void enemy::drawzcboss(BITMAP *dest)
6351 {
6352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 165500 times.
165500 if(dont_draw())
6353 return;
6354
6355 165500 int32_t cshold=cs;
6356
6357
2/2
✓ Branch 0 taken 6444 times.
✓ Branch 1 taken 159056 times.
165500 if(dying)
6358 {
6359
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6444 times.
6444 if(clk2>=19)
6360 {
6361 if(!(clk2&2))
6362 sprite::drawzcboss(dest);
6363
6364 return;
6365 }
6366
6367 6444 flip = 0;
6368 6444 tile = wpnsbuf[spr_death].tile;
6369
6370
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6444 times.
6444 if ( do_animation )
6371 {
6372
1/2
✓ Branch 0 taken 6444 times.
✗ Branch 1 not taken.
6444 if(!get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS))
6373 {
6374 if(clk2 > 2)
6375 {
6376 spr_death_anim_clk=0;
6377 clk2=1;
6378 if(hp > -1000)
6379 death_sfx();
6380 }
6381 if(clk2==1 && spr_death_anim_clk>-1)
6382 {
6383 ++clk2;
6384 spr_death_anim_frm=(spr_death_anim_clk/zc_max(wpnsbuf[spr_death].speed,1));
6385 spr_death_anim_frm *= zc_max(1,txsz);
6386 int32_t rows = TILEROW(tile+spr_death_anim_frm)-TILEROW(tile);
6387 spr_death_anim_frm += TILES_PER_ROW*(zc_min(0,tysz-1)*rows);
6388 if(++spr_death_anim_clk >= (zc_max(wpnsbuf[spr_death].speed,1) * zc_max(wpnsbuf[spr_death].frames,1)))
6389 {
6390 spr_death_anim_clk=-1;
6391 clk2=1;
6392 }
6393 }
6394 tile += spr_death_anim_frm;
6395 }
6396
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6444 times.
6444 else if(BSZ)
6397 tile += zc_min((15-clk2)/3,4);
6398
4/4
✓ Branch 0 taken 4126 times.
✓ Branch 1 taken 2318 times.
✓ Branch 2 taken 2068 times.
✓ Branch 3 taken 2058 times.
6444 else if(clk2>6 && clk2<=12)
6399 2058 ++tile;
6400 6444 }
6401
6402
4/6
✓ Branch 0 taken 6444 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6444 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1916 times.
✓ Branch 5 taken 4528 times.
6444 if(!get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS) || BSZ || fading==fade_blue_poof)
6403 1916 cs = wpnsbuf[spr_death].csets&15;
6404 else
6405 4528 cs = (((clk2+5)>>1)&3)+6;
6406 6444 }
6407
2/2
✓ Branch 0 taken 153067 times.
✓ Branch 1 taken 5989 times.
159056 else if(hclk>0)
6408 {
6409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5989 times.
5989 if(family==eeGANON)
6410 cs=(((hclk-1)>>1)&3)+6;
6411
3/4
✓ Branch 0 taken 5470 times.
✓ Branch 1 taken 519 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5470 times.
5989 else if(hclk<33 && !get_bit(quest_rules,qr_ENEMIESFLICKER))
6412 5470 cs=(((hclk-1)>>1)&3)+6;
6413 5989 }
6414
6415
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 165500 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
165500 if((tmpscr->flags3&fINVISROOM) &&
6416 !(current_item(itype_amulet)) &&
6417 !(get_bit(quest_rules,qr_LENSSEESENEMIES) &&
6418 lensclk) && family!=eeGANON)
6419 {
6420 sprite::drawcloaked(dest);
6421 }
6422 else
6423 {
6424
5/6
✓ Branch 0 taken 165500 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12433 times.
✓ Branch 3 taken 153067 times.
✓ Branch 4 taken 12263 times.
✓ Branch 5 taken 170 times.
165500 if(family !=eeGANON && hclk>0 && get_bit(quest_rules,qr_ENEMIESFLICKER))
6425 {
6426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170 times.
170 if((frame&1)==1)
6427 170 sprite::drawzcboss(dest);
6428 170 }
6429 else
6430 165330 sprite::drawzcboss(dest);
6431 }
6432
6433 165500 cs=cshold;
6434 165500 }
6435
6436
6437 // similar to the overblock function--can do up to a 32x32 sprite
6438 //will this play nicely with scripttile, solely using the modifications in sprite::draw()?
6439 396 void enemy::drawblock(BITMAP *dest,int32_t mask)
6440 {
6441 396 int32_t thold=tile;
6442 396 int32_t t1=tile;
6443 396 int32_t t2=tile+20;
6444 396 int32_t t3=tile+1;
6445 396 int32_t t4=tile+21;
6446
6447
1/5
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 396 times.
396 switch(mask)
6448 {
6449 case 1:
6450 enemy::drawzcboss(dest);
6451 break;
6452
6453 case 3:
6454 if(flip&2)
6455 zc_swap(t1,t2);
6456
6457 tile=t1;
6458 enemy::drawzcboss(dest);
6459 tile=t2;
6460 yofs+=16;
6461 enemy::drawzcboss(dest);
6462 yofs-=16;
6463 break;
6464
6465 case 5:
6466 t2=tile+1;
6467
6468 if(flip&1)
6469 zc_swap(t1,t2);
6470
6471 tile=t1;
6472 enemy::drawzcboss(dest);
6473 tile=t2;
6474 xofs+=16;
6475 enemy::drawzcboss(dest);
6476 xofs-=16;
6477 break;
6478
6479 case 15:
6480
1/2
✓ Branch 0 taken 396 times.
✗ Branch 1 not taken.
396 if(flip&1)
6481 {
6482 zc_swap(t1,t3);
6483 zc_swap(t2,t4);
6484 }
6485
6486
1/2
✓ Branch 0 taken 396 times.
✗ Branch 1 not taken.
396 if(flip&2)
6487 {
6488 zc_swap(t1,t2);
6489 zc_swap(t3,t4);
6490 }
6491
6492 396 tile=t1;
6493 396 enemy::drawzcboss(dest);
6494 396 tile=t2;
6495 396 yofs+=16;
6496 396 enemy::drawzcboss(dest);
6497 396 yofs-=16;
6498 396 tile=t3;
6499 396 xofs+=16;
6500 396 enemy::drawzcboss(dest);
6501 396 tile=t4;
6502 396 yofs+=16;
6503 396 enemy::drawzcboss(dest);
6504 396 xofs-=16;
6505 396 yofs-=16;
6506 396 break;
6507 }
6508
6509 396 tile=thold;
6510 396 }
6511
6512 40672 void enemy::drawshadow(BITMAP *dest, bool translucent)
6513 {
6514
3/4
✓ Branch 0 taken 39172 times.
✓ Branch 1 taken 1500 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 39172 times.
40672 if(dont_draw() || isSideViewGravity())
6515 {
6516 1500 return;
6517 }
6518
6519
2/2
✓ Branch 0 taken 1278 times.
✓ Branch 1 taken 37894 times.
39172 if(dying)
6520 {
6521 1278 return;
6522 }
6523
6524
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 37894 times.
✓ Branch 2 taken 5118 times.
✓ Branch 3 taken 32776 times.
37894 if(((tmpscr->flags3&fINVISROOM)&& !(current_item(itype_amulet)))||
6525 37894 (darkroom))
6526 {
6527 5118 return;
6528 }
6529 else
6530 {
6531
4/4
✓ Branch 0 taken 31884 times.
✓ Branch 1 taken 892 times.
✓ Branch 2 taken 31770 times.
✓ Branch 3 taken 114 times.
32776 if(enemycanfall(id, false) && shadowtile == 0)
6532 114 shadowtile = wpnsbuf[spr_shadow].tile;
6533
6534
5/6
✓ Branch 0 taken 29033 times.
✓ Branch 1 taken 3743 times.
✓ Branch 2 taken 29033 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 28141 times.
✓ Branch 5 taken 892 times.
32776 if(z>0 || fakez>0 || !enemycanfall(id, false))
6535 {
6536
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4635 times.
4635 if(!shadow_overpit(this))
6537 4635 sprite::drawshadow(dest,translucent);
6538 4635 }
6539 }
6540 40672 }
6541
6542 3213 void enemy::masked_draw(BITMAP *dest,int32_t mx,int32_t my,int32_t mw,int32_t mh)
6543 {
6544 3213 BITMAP *sub=create_sub_bitmap(dest,mx,my,mw,mh);
6545
6546
1/2
✓ Branch 0 taken 3213 times.
✗ Branch 1 not taken.
3213 if(sub!=NULL)
6547 {
6548 3213 xofs-=mx;
6549 3213 yofs-=my;
6550 3213 enemy::draw(sub);
6551 3213 xofs+=mx;
6552 3213 yofs+=my;
6553 3213 destroy_bitmap(sub);
6554 3213 }
6555 else
6556 enemy::draw(dest);
6557 3213 }
6558
6559 // override hit detection to check for invicibility, stunned, etc
6560 bool enemy::hit(sprite *s)
6561 {
6562 if(!(s->scriptcoldet&1) || s->fallclk || s->drownclk) return false;
6563
6564 return (dying || hclk>0) ? false : sprite::hit(s);
6565 }
6566
6567 159498 bool enemy::hit(int32_t tx,int32_t ty,int32_t tz,int32_t txsz2,int32_t tysz2,int32_t tzsz2)
6568 {
6569
4/4
✓ Branch 0 taken 154206 times.
✓ Branch 1 taken 5292 times.
✓ Branch 2 taken 149001 times.
✓ Branch 3 taken 5205 times.
159498 return (dying || hclk>0) ? false : sprite::hit(tx,ty,tz,txsz2,tysz2,tzsz2);
6570 }
6571 bool enemy::hit(int32_t tx,int32_t ty,int32_t txsz2,int32_t tysz2)
6572 {
6573 return (dying || hclk>0) ? false : sprite::hit(tx,ty,txsz2,tysz2);
6574 }
6575
6576 20536 bool enemy::hit(weapon *w)
6577 {
6578
3/6
✓ Branch 0 taken 20536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20536 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 20536 times.
20536 if(!(w->scriptcoldet&1) || w->fallclk || w->drownclk) return false;
6579
6580
4/4
✓ Branch 0 taken 19543 times.
✓ Branch 1 taken 993 times.
✓ Branch 2 taken 18954 times.
✓ Branch 3 taken 589 times.
20536 return (dying || hclk>0) ? false : sprite::hit(w);
6581 20536 }
6582
6583 81261 bool enemy::can_pitfall(bool checkspawning)
6584 {
6585
4/4
✓ Branch 0 taken 81251 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 80951 times.
✓ Branch 3 taken 310 times.
81261 if((fading||isspawning)&&checkspawning) return false; //Don't fall during spawn.
6586
2/2
✓ Branch 0 taken 80907 times.
✓ Branch 1 taken 44 times.
80951 switch(guysbuf[id&0xFFF].family)
6587 {
6588 case eeAQUA:
6589 case eeDIG:
6590 case eeDONGO:
6591 case eeFAIRY:
6592 case eeGANON:
6593 case eeGHOMA:
6594 case eeGLEEOK:
6595 case eeGUY:
6596 case eeLANM:
6597 case eeMANHAN:
6598 case eeMOLD:
6599 case eeNONE:
6600 case eePATRA:
6601 case eeZORA:
6602 44 return false; //Disallowed types
6603 default:
6604 80907 return true;
6605 }
6606 81261 }
6607 //Handle death
6608 138890 void enemy::try_death(bool force_kill)
6609 {
6610
5/8
✓ Branch 0 taken 138890 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 138890 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 248 times.
✓ Branch 5 taken 138642 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 248 times.
138890 if(!dying && (force_kill || (hp<=0 && !immortal)))
6611 {
6612 248 std::vector<int32_t> &ev = FFCore.eventData;
6613 248 ev.clear();
6614 248 ev.push_back(10000);
6615 248 ev.push_back(getUID());
6616
6617 248 throwGenScriptEvent(GENSCR_EVENT_ENEMY_DEATH);
6618 248 bool isSaved = !ev[0];
6619 248 ev.clear();
6620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 248 times.
248 if(isSaved) return;
6621
6622
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 245 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
248 if(itemguy && (hasitem&2)!=0)
6623 {
6624
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for(int32_t i=0; i<items.Count(); i++)
6625 {
6626
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(((item*)items.spr(i))->pickup&ipENEMY)
6627 {
6628
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!get_bit(quest_rules, qr_BROKEN_ITEM_CARRYING))
6629 {
6630 if (get_bit(quest_rules, qr_ENEMY_DROPS_USE_HITOFFSETS))
6631 {
6632 items.spr(i)->x = x+hxofs+(hxsz/2)-8;
6633 items.spr(i)->y = y+hyofs+(hysz/2)-10-fakez;
6634 }
6635 else
6636 {
6637 if(extend >= 3)
6638 {
6639 items.spr(i)->x = x+(txsz-1)*8;
6640 items.spr(i)->y = y-2+(tysz-1)*8;
6641 }
6642 else
6643 {
6644 items.spr(i)->x = x;
6645 items.spr(i)->y = y - 2;
6646 }
6647 }
6648 items.spr(i)->z = z;
6649 items.spr(i)->fakez = fakez;
6650 }
6651 else
6652 {
6653 3 items.spr(i)->x = x;
6654 3 items.spr(i)->y = y - 2;
6655 }
6656 3 }
6657 3 }
6658 3 }
6659
6660 248 dying=true;
6661
6662
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 248 times.
248 if(fading==fade_flash_die)
6663 clk2=19+18*4;
6664 else
6665 {
6666 248 clk2 = BSZ ? 15 : 19;
6667
6668
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 196 times.
248 if(fading!=fade_blue_poof)
6669 196 fading=0;
6670 }
6671
6672
2/2
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 3 times.
248 if(itemguy)
6673 {
6674 3 hasitem&=~2;
6675 3 item_set=0;
6676 3 }
6677
6678
4/6
✓ Branch 0 taken 243 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 243 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 243 times.
248 if(currscr<128 && count_enemy && !script_spawned)
6679 243 game->guys[(currmap<<7)+currscr]-=1;
6680 248 }
6681 138890 }
6682
6683 // --==**==--
6684
6685 // Movement routines that can be used by derived classes as needed
6686
6687 // --==**==--
6688
6689 2333 void enemy::fix_coords(bool bound)
6690 {
6691
1/2
✓ Branch 0 taken 2333 times.
✗ Branch 1 not taken.
2333 if ((get_bit(quest_rules,qr_OUTOFBOUNDSENEMIES) ? 1 : 0) ^ ((editorflags&ENEMY_FLAG11)?1:0)) return;
6692
1/2
✓ Branch 0 taken 2333 times.
✗ Branch 1 not taken.
2333 if(moveflags & FLAG_IGNORE_SCREENEDGE) bound = false;
6693
6694
6695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2333 times.
2333 if(bound)
6696 {
6697
1/2
✓ Branch 0 taken 2333 times.
✗ Branch 1 not taken.
2333 if ( ((unsigned)(id&0xFFF)) < MAXGUYS )
6698 {
6699
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2333 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2333 x=vbound(x, 0, (( guysbuf[id].SIZEflags&guyflagOVERRIDE_TILE_WIDTH && !isflier(id) ) ? (256-((txsz-1)*16)) : 240));
6700
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2333 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2333 y=vbound(y, 0,(( guysbuf[id].SIZEflags&guyflagOVERRIDE_TILE_HEIGHT && !isflier(id) ) ? (176-((txsz-1)*16)) : 160));
6701 2333 }
6702 else
6703 {
6704 x=vbound(x, 0,240);
6705 y=vbound(y, 0,160);
6706 }
6707 2333 }
6708
6709
5/10
✓ Branch 0 taken 2333 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2333 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2333 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2333 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2333 times.
2333 if(!OUTOFBOUNDS)
6710 {
6711 /*x=((int32_t(x)&0xF0)+((int32_t(x)&8)?16:0));
6712
6713 if(isSideViewGravity())
6714 y=((int32_t(y)&0xF8)+((int32_t(y)&4)?8:0));
6715 else
6716 y=((int32_t(y)&0xF0)+((int32_t(y)&8)?16:0));
6717 */
6718 2333 do_fix(x, 16, true);
6719
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2333 times.
2333 if(isSideViewGravity())
6720 do_fix(y,8,true);
6721 2333 else do_fix(y,16,true);
6722 2333 }
6723 2333 }
6724 151 bool enemy::cannotpenetrate()
6725 {
6726
3/4
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 139 times.
151 return (family == eeAQUA || family == eeMANHAN || family == eeGHOMA);
6727 }
6728
6729 bool enemy::canmove_old(int32_t ndir,zfix s,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2)
6730 {
6731 bool ok;
6732 int32_t dx = 0, dy = 0;
6733 int32_t sv = 8;
6734
6735 //Why is this here??? Why is it needed???
6736 s += 0.5; // Make the ints round; doesn't seem to cause any problems.
6737
6738 switch(ndir)
6739 {
6740 case 8:
6741 case up:
6742 if(canfall(id) && isSideViewGravity())
6743 return false;
6744
6745 dy = dy1-s;
6746 special = (special==spw_clipbottomright)?spw_none:special;
6747 ok = !m_walkflag_old(x,y+dy,special, x, y) && !flyerblocked(x,y+dy, special);
6748 break;
6749
6750 case 12:
6751 case down:
6752 if(canfall(id) && isSideViewGravity())
6753 return false;
6754
6755 dy = dy2+s;
6756 ok = !m_walkflag_old(x,y+dy,special, x, y) && !flyerblocked(x,y+dy, special);
6757 break;
6758
6759 case 14:
6760 case left:
6761 dx = dx1-s;
6762 sv = ((isSideViewGravity())?7:8);
6763 special = (special==spw_clipbottomright||special==spw_clipright)?spw_none:special;
6764 ok = !m_walkflag_old(x+dx,y+sv,special, x, y) && !flyerblocked(x+dx,y+8, special);
6765 break;
6766
6767 case 10:
6768 case right:
6769 dx = dx2+s;
6770 sv = ((isSideViewGravity())?7:8);
6771 ok = !m_walkflag_old(x+dx,y+sv,special, x, y) && !flyerblocked(x+dx,y+8, special);
6772 break;
6773
6774 case 9:
6775 case r_up:
6776 dx = dx2+s;
6777 dy = dy1-s;
6778 ok = !m_walkflag_old(x,y+dy,special, x, y) && !m_walkflag_old(x+dx,y+sv,special, x, y) &&
6779 !flyerblocked(x,y+dy, special) && !flyerblocked(x+dx,y+8, special);
6780 break;
6781
6782 case 11:
6783 case r_down:
6784 dx = dx2+s;
6785 dx = dy2+s;
6786 ok = !m_walkflag_old(x,y+dy,special, x, y) && !m_walkflag_old(x+dx,y+sv,special, x, y) &&
6787 !flyerblocked(x,y+dy, special) && !flyerblocked(x+dx,y+8, special);
6788 break;
6789
6790 case 13:
6791 case l_down:
6792 dx = dx1-s;
6793 dy = dy2+s;
6794 ok = !m_walkflag_old(x,y+dy,special, x, y) && !m_walkflag_old(x+dx,y+sv,special, x, y) &&
6795 !flyerblocked(x,y+dy, special) && !flyerblocked(x+dx,y+8, special);
6796 break;
6797
6798 case 15:
6799 case l_up:
6800 dx = dx1-s;
6801 dy = dy1-s;
6802 ok = !m_walkflag_old(x,y+dy,special, x, y) && !m_walkflag_old(x+dx,y+sv,special, x, y) &&
6803 !flyerblocked(x,y+dy, special) && !flyerblocked(x+dx,y+8, special);
6804 break;
6805
6806 default:
6807 db=99;
6808 return true;
6809 }
6810
6811 return ok;
6812 }
6813
6814
6815
6816
6817 // returns true if next step is ok, false if there is something there
6818 33623 bool enemy::canmove(int32_t ndir,zfix s,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2, bool kb)
6819 {
6820 33623 bool ok = false; //initialise the var, son't just declare it
6821 33623 int32_t dx = 0, dy = 0;
6822 33623 int32_t sv = 8;
6823 33623 int32_t tries = 2; int32_t try_x = 0; int32_t try_y = 0;
6824 //Why is this here??? Why is it needed???
6825 33623 s += 0.5; // Make the ints round; doesn't seem to cause any problems.
6826
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33623 times.
33623 int32_t usexoffs = (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) ? hxofs : 0;
6827
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33623 times.
33623 int32_t useyoffs = (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) ? hyofs : 0;
6828
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33623 times.
33623 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ? hxsz : 16;
6829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33623 times.
33623 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ? hysz : 16;
6830 33623 bool offgrid = OFFGRID_ENEMY;
6831
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33623 times.
33623 if(!offgrid)
6832 {
6833 //Enemies smaller than 1-tile must act as 1-tile large, if off-grid movement is disabled.
6834
1/2
✓ Branch 0 taken 33623 times.
✗ Branch 1 not taken.
33623 if(usehei<16)usehei=16;
6835
1/2
✓ Branch 0 taken 33623 times.
✗ Branch 1 not taken.
33623 if(usewid<16)usewid=16;
6836 33623 }
6837
8/9
✓ Branch 0 taken 5325 times.
✓ Branch 1 taken 4881 times.
✓ Branch 2 taken 5351 times.
✓ Branch 3 taken 4775 times.
✓ Branch 4 taken 2996 times.
✓ Branch 5 taken 4534 times.
✓ Branch 6 taken 3584 times.
✓ Branch 7 taken 2177 times.
✗ Branch 8 not taken.
33623 switch(ndir) //need to check every 8 pixels between two points
6838 {
6839 case 8:
6840 case up:
6841 {
6842
3/4
✓ Branch 0 taken 1062 times.
✓ Branch 1 taken 4263 times.
✓ Branch 2 taken 1062 times.
✗ Branch 3 not taken.
5325 if(enemycanfall(id) && isSideViewGravity())
6843 return false;
6844
6845 5325 dy = dy1-s;
6846
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5325 times.
5325 special = (special==spw_clipbottomright)?spw_none:special;
6847 5325 tries = usewid/(offgrid ? 8 : 16);
6848 //Z_eventlog("Trying move UP, dy=%d,usewid=%d,usehei=%d\n",int32_t(dy),usewid,usehei);
6849
2/2
✓ Branch 0 taken 4749 times.
✓ Branch 1 taken 5325 times.
10074 for ( ; tries > 0; --tries )
6850 {
6851
2/2
✓ Branch 0 taken 563 times.
✓ Branch 1 taken 4762 times.
5325 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy,special, ndir, x+usexoffs+try_x, y+useyoffs, kb) && !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy, special,kb);
6852 5325 try_x += (offgrid ? 8 : 16);
6853
2/2
✓ Branch 0 taken 4749 times.
✓ Branch 1 taken 576 times.
5325 if (!ok) break;
6854 4749 }
6855
2/2
✓ Branch 0 taken 4749 times.
✓ Branch 1 taken 576 times.
5325 if(!ok) break;
6856
1/2
✓ Branch 0 taken 4749 times.
✗ Branch 1 not taken.
4749 if((usewid%16)>0) //Uneven width
6857 {
6858 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy,special, ndir, x+usexoffs+usewid-1, y+useyoffs, kb) && !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy, special,kb);
6859 }
6860 4749 break;
6861 }
6862 case 12:
6863 case down:
6864 {
6865
3/4
✓ Branch 0 taken 1093 times.
✓ Branch 1 taken 3788 times.
✓ Branch 2 taken 1093 times.
✗ Branch 3 not taken.
4881 if(enemycanfall(id) && isSideViewGravity())
6866 return false;
6867
6868 4881 dy = dy2+s;
6869 4881 tries = usewid/(offgrid ? 8 : 16);
6870 //Z_eventlog("Trying move DOWN, dy=%d,usewid=%d,usehei=%d\n",int32_t(dy),usewid,usehei);
6871
2/2
✓ Branch 0 taken 4278 times.
✓ Branch 1 taken 4881 times.
9159 for ( ; tries > 0; --tries )
6872 {
6873
3/4
✓ Branch 0 taken 603 times.
✓ Branch 1 taken 4278 times.
✓ Branch 2 taken 4278 times.
✗ Branch 3 not taken.
4881 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy,special, ndir, x+usexoffs+try_x, y+useyoffs, kb) && !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+zc_max(usehei-16,0), special,kb);
6874 4881 try_x += (offgrid ? 8 : 16);
6875
2/2
✓ Branch 0 taken 4278 times.
✓ Branch 1 taken 603 times.
4881 if (!ok) break;
6876 4278 }
6877
2/2
✓ Branch 0 taken 4278 times.
✓ Branch 1 taken 603 times.
4881 if(!ok) break;
6878
1/2
✓ Branch 0 taken 4278 times.
✗ Branch 1 not taken.
4278 if((usewid%16)>0) //Uneven width
6879 {
6880 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy,special, ndir, x+usexoffs+usewid-1, y+useyoffs, kb) && !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+zc_max(usehei-16,0), special,kb);
6881 }
6882 4278 break;
6883 }
6884 case 14:
6885 case left:
6886 {
6887 5351 dx = dx1-s;
6888 5351 sv = ((isSideViewGravity())?7:0);
6889
3/4
✓ Branch 0 taken 5351 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 5350 times.
5351 special = (special==spw_clipbottomright||special==spw_clipright)?spw_none:special;
6890 5351 tries = usehei/(offgrid ? 8 : 16);
6891 //Z_eventlog("Trying move LEFT, dx=%d,usewid=%d,usehei=%d\n",int32_t(dx),usewid,usehei);
6892
2/2
✓ Branch 0 taken 4962 times.
✓ Branch 1 taken 5351 times.
10313 for ( ; tries > 0; --tries )
6893 {
6894
2/2
✓ Branch 0 taken 386 times.
✓ Branch 1 taken 4965 times.
5351 ok = !m_walkflag(x+usexoffs+dx,y+useyoffs+try_y+sv,special, ndir, x+usexoffs, y+useyoffs+try_y, kb) && !flyerblocked(x+usexoffs+dx,y+8+useyoffs+try_y, special,kb);
6895 5351 try_y += (offgrid ? 8 : 16);
6896
2/2
✓ Branch 0 taken 4962 times.
✓ Branch 1 taken 389 times.
5351 if (!ok) break;
6897 4962 }
6898
2/2
✓ Branch 0 taken 4962 times.
✓ Branch 1 taken 389 times.
5351 if(!ok) break;
6899
1/2
✓ Branch 0 taken 4962 times.
✗ Branch 1 not taken.
4962 if((usehei%16)>0) //Uneven height
6900 {
6901 ok = !m_walkflag(x+usexoffs+dx,y+useyoffs+usehei-1+sv,special, ndir, x+usexoffs, y+useyoffs+usehei-1, kb) && !flyerblocked(x+usexoffs+dx,y+8+useyoffs+usehei-1, special,kb);
6902 }
6903 4962 break;
6904 }
6905 case 10:
6906 case right:
6907 {
6908 4775 dx = dx2+s;
6909 4775 sv = ((isSideViewGravity())?7:0);
6910 4775 tries = usehei/(offgrid ? 8 : 16);
6911 //Z_eventlog("Trying move RIGHT, dx=%d,usewid=%d,usehei=%d\n",int32_t(dx),usewid,usehei);
6912
2/2
✓ Branch 0 taken 4331 times.
✓ Branch 1 taken 4775 times.
9106 for ( ; tries > 0; --tries )
6913 {
6914
3/4
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 4336 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4336 times.
4775 ok = !m_walkflag(x+usexoffs+dx,y+useyoffs+try_y+sv,special, ndir, x+usexoffs, y+useyoffs+try_y, kb) && !flyerblocked(x+usexoffs+dx+zc_max(usewid-16,0),y+8+useyoffs+try_y, special,kb);
6915 4775 try_y += (offgrid ? 8 : 16);
6916
2/2
✓ Branch 0 taken 4331 times.
✓ Branch 1 taken 444 times.
4775 if (!ok) break;
6917 4331 }
6918
2/2
✓ Branch 0 taken 4331 times.
✓ Branch 1 taken 444 times.
4775 if(!ok) break;
6919
1/2
✓ Branch 0 taken 4331 times.
✗ Branch 1 not taken.
4331 if((usehei%16)>0) //Uneven height
6920 {
6921 ok = !m_walkflag(x+usexoffs+dx,y+useyoffs+usehei-1+sv,special, ndir, x+usexoffs, y+useyoffs+usehei-1, kb) && !flyerblocked(x+usexoffs+dx+zc_max(usewid-16,0),y+8+useyoffs+usehei-1, special,kb);
6922 }
6923 4331 break;
6924 }
6925 case 9:
6926 case r_up:
6927 {
6928 2996 dx = dx2+s;
6929 2996 dy = dy1-s;
6930 2996 int32_t tries_x = usewid/(offgrid ? 8 : 16);
6931 2996 sv = ((isSideViewGravity())?7:0);
6932
2/2
✓ Branch 0 taken 2909 times.
✓ Branch 1 taken 2996 times.
5905 for ( ; tries_x > 0; --tries_x )
6933 {
6934 2996 int32_t tries_y = usehei/(offgrid ? 8 : 16);
6935 2996 try_y = 0;
6936
2/2
✓ Branch 0 taken 2909 times.
✓ Branch 1 taken 2996 times.
5905 for ( ; tries_y > 0; --tries_y )
6937 {
6938
4/4
✓ Branch 0 taken 2949 times.
✓ Branch 1 taken 47 times.
✓ Branch 2 taken 2932 times.
✓ Branch 3 taken 17 times.
5928 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) &&
6939
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2916 times.
2932 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+try_y, special,kb);
6940 2996 try_y += (offgrid ? 8 : 16);
6941
2/2
✓ Branch 0 taken 2909 times.
✓ Branch 1 taken 87 times.
2996 if (!ok) break;
6942 2909 }
6943
2/2
✓ Branch 0 taken 2909 times.
✓ Branch 1 taken 87 times.
2996 if (!ok) break;
6944
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2909 times.
2909 if((usehei%16)>0) //Uneven height
6945 {
6946 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) &&
6947 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+usehei-1, special,kb);
6948 }
6949 2909 try_x += (offgrid ? 8 : 16);
6950 2909 }
6951
2/2
✓ Branch 0 taken 2909 times.
✓ Branch 1 taken 87 times.
2996 if(!ok) break;
6952
1/2
✓ Branch 0 taken 2909 times.
✗ Branch 1 not taken.
2909 if((usewid%16)>0) //Uneven width
6953 {
6954 int32_t tries_y = usehei/(offgrid ? 8 : 16);
6955 try_y = 0;
6956 for ( ; tries_y > 0; --tries_y )
6957 {
6958 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) &&
6959 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+try_y, special,kb);
6960 try_y += (offgrid ? 8 : 16);
6961 if (!ok) break;
6962 }
6963 if (!ok) break;
6964 if((usehei%16)>0) //Uneven height
6965 {
6966 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) &&
6967 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+usehei-1, special,kb);
6968 }
6969 }
6970 2909 break;
6971 }
6972 case 11:
6973 case r_down:
6974 {
6975 4534 dx = dx2+s;
6976 4534 dx = dy2+s;
6977 4534 int32_t tries_x = usewid/(offgrid ? 8 : 16);
6978 //sv = ((isSideViewGravity())?7:0);
6979
2/2
✓ Branch 0 taken 4457 times.
✓ Branch 1 taken 4534 times.
8991 for ( ; tries_x > 0; --tries_x )
6980 {
6981 4534 int32_t tries_y = usehei/(offgrid ? 8 : 16);
6982 4534 try_y = 0;
6983
2/2
✓ Branch 0 taken 4457 times.
✓ Branch 1 taken 4534 times.
8991 for ( ; tries_y > 0; --tries_y )
6984 {
6985
3/4
✓ Branch 0 taken 4534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4457 times.
✓ Branch 3 taken 77 times.
8991 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) &&
6986
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4457 times.
4457 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+try_y, special,kb);
6987 4534 try_y += (offgrid ? 8 : 16);
6988
2/2
✓ Branch 0 taken 4457 times.
✓ Branch 1 taken 77 times.
4534 if (!ok) break;
6989 4457 }
6990
2/2
✓ Branch 0 taken 4457 times.
✓ Branch 1 taken 77 times.
4534 if (!ok) break;
6991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4457 times.
4457 if((usehei%16)>0) //Uneven height
6992 {
6993 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) &&
6994 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+usehei-1, special,kb);
6995 }
6996 4457 try_x += (offgrid ? 8 : 16);
6997 4457 }
6998
2/2
✓ Branch 0 taken 4457 times.
✓ Branch 1 taken 77 times.
4534 if(!ok) break;
6999
1/2
✓ Branch 0 taken 4457 times.
✗ Branch 1 not taken.
4457 if((usewid%16)>0) //Uneven width
7000 {
7001 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7002 try_y = 0;
7003 for ( ; tries_y > 0; --tries_y )
7004 {
7005 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) &&
7006 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+try_y, special,kb);
7007 try_y += (offgrid ? 8 : 16);
7008 if (!ok) break;
7009 }
7010 if (!ok) break;
7011 if((usehei%16)>0) //Uneven height
7012 {
7013 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) &&
7014 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+usehei-1, special,kb);
7015 }
7016 }
7017 4457 break;
7018 }
7019 case 13:
7020 case l_down:
7021 {
7022 3584 dx = dx1-s;
7023 3584 dy = dy2+s;
7024 3584 int32_t tries_x = usewid/(offgrid ? 8 : 16);
7025 //sv = ((isSideViewGravity())?7:0);
7026
2/2
✓ Branch 0 taken 3535 times.
✓ Branch 1 taken 3584 times.
7119 for ( ; tries_x > 0; --tries_x )
7027 {
7028 3584 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7029 3584 try_y = 0;
7030
2/2
✓ Branch 0 taken 3535 times.
✓ Branch 1 taken 3584 times.
7119 for ( ; tries_y > 0; --tries_y )
7031 {
7032
4/4
✓ Branch 0 taken 3553 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 3535 times.
✓ Branch 3 taken 18 times.
7119 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) &&
7033
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3535 times.
3535 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+try_y, special,kb);
7034 3584 try_y += (offgrid ? 8 : 16);
7035
2/2
✓ Branch 0 taken 3535 times.
✓ Branch 1 taken 49 times.
3584 if (!ok) break;
7036 3535 }
7037
2/2
✓ Branch 0 taken 3535 times.
✓ Branch 1 taken 49 times.
3584 if (!ok) break;
7038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3535 times.
3535 if((usehei%16)>0) //Uneven height
7039 {
7040 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) &&
7041 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+usehei-1, special,kb);
7042 }
7043 3535 try_x += (offgrid ? 8 : 16);
7044 3535 }
7045
2/2
✓ Branch 0 taken 3535 times.
✓ Branch 1 taken 49 times.
3584 if(!ok) break;
7046
1/2
✓ Branch 0 taken 3535 times.
✗ Branch 1 not taken.
3535 if((usewid%16)>0) //Uneven width
7047 {
7048 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7049 try_y = 0;
7050 for ( ; tries_y > 0; --tries_y )
7051 {
7052 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) &&
7053 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+try_y, special,kb);
7054 try_y += (offgrid ? 8 : 16);
7055 if (!ok) break;
7056 }
7057 if (!ok) break;
7058 if((usehei%16)>0) //Uneven height
7059 {
7060 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) &&
7061 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+usehei-1, special,kb);
7062 }
7063 }
7064 3535 break;
7065 }
7066 case 15:
7067 case l_up:
7068 {
7069 2177 dx = dx1-s;
7070 2177 dy = dy1-s;
7071 2177 int32_t tries_x = usewid/(offgrid ? 8 : 16);
7072 2177 sv = ((isSideViewGravity())?7:0);
7073
2/2
✓ Branch 0 taken 2116 times.
✓ Branch 1 taken 2177 times.
4293 for ( ; tries_x > 0; --tries_x )
7074 {
7075 2177 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7076 2177 try_y = 0;
7077
2/2
✓ Branch 0 taken 2116 times.
✓ Branch 1 taken 2177 times.
4293 for ( ; tries_y > 0; --tries_y )
7078 {
7079
4/4
✓ Branch 0 taken 2132 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 2124 times.
✓ Branch 3 taken 8 times.
4301 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) &&
7080
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2117 times.
2124 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+try_y, special,kb);
7081 2177 try_y += (offgrid ? 8 : 16);
7082
2/2
✓ Branch 0 taken 2116 times.
✓ Branch 1 taken 61 times.
2177 if (!ok) break;
7083 2116 }
7084
2/2
✓ Branch 0 taken 2116 times.
✓ Branch 1 taken 61 times.
2177 if (!ok) break;
7085
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2116 times.
2116 if((usehei%16)>0) //Uneven height
7086 {
7087 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) &&
7088 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+usehei-1, special,kb);
7089 }
7090 2116 try_x += (offgrid ? 8 : 16);
7091 2116 }
7092
2/2
✓ Branch 0 taken 2116 times.
✓ Branch 1 taken 61 times.
2177 if(!ok) break;
7093
1/2
✓ Branch 0 taken 2116 times.
✗ Branch 1 not taken.
2116 if((usewid%16)>0) //Uneven width
7094 {
7095 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7096 try_y = 0;
7097 for ( ; tries_y > 0; --tries_y )
7098 {
7099 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) &&
7100 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+try_y, special,kb);
7101 try_y += (offgrid ? 8 : 16);
7102 if (!ok) break;
7103 }
7104 if (!ok) break;
7105 if((usehei%16)>0) //Uneven height
7106 {
7107 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) &&
7108 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+usehei-1, special,kb);
7109 }
7110 }
7111 2116 break;
7112 }
7113 default:
7114 db=99;
7115 return true;
7116 }
7117 //Z_eventlog("\n");
7118 33623 return ok;
7119 33623 }
7120
7121
7122 25186 bool enemy::canmove(int32_t ndir,zfix s,int32_t special, bool kb)
7123 {
7124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25186 times.
25186 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ? hxsz : 16;
7125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25186 times.
25186 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ? hysz : 16;
7126
1/2
✓ Branch 0 taken 25186 times.
✗ Branch 1 not taken.
25186 if (usewid % 16 != 0) usewid += (16 - (usewid%16));
7127
1/2
✓ Branch 0 taken 25186 times.
✗ Branch 1 not taken.
25186 if (usehei % 16 != 0) usehei += (16 - (usehei%16));
7128 25186 --usewid;
7129 25186 --usehei;
7130 25186 return canmove(ndir,s,special,0,-8,usewid,usehei,kb);
7131 }
7132
7133 4165 bool enemy::canmove(int32_t ndir,int32_t special, bool kb)
7134 {
7135 4165 bool dodongo_move=true; //yes, it's an ugly hack, but we're going to rewrite everything later anyway - DN
7136
7137
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4162 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
4165 if(special==spw_clipright&&ndir==right)
7138 {
7139 dodongo_move=canmove(ndir,(zfix)1,special,0,-8,31,15,kb);
7140 }
7141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4165 times.
4165 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ? hxsz : 16;
7142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4165 times.
4165 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ? hysz : 16;
7143
1/2
✓ Branch 0 taken 4165 times.
✗ Branch 1 not taken.
4165 if (usewid % 16 != 0) usewid += (16 - (usewid%16));
7144
1/2
✓ Branch 0 taken 4165 times.
✗ Branch 1 not taken.
4165 if (usehei % 16 != 0) usehei += (16 - (usehei%16));
7145 4165 --usewid;
7146 4165 --usehei;
7147
2/2
✓ Branch 0 taken 1830 times.
✓ Branch 1 taken 2335 times.
4165 return canmove(ndir,(zfix)1,special,0,-8,usewid,usehei,kb)&&dodongo_move;
7148 }
7149
7150 186 bool enemy::canmove(int32_t ndir, bool kb)
7151 {
7152 186 return canmove(ndir,(zfix)1,spw_none,0,-8,15,15,kb);
7153 }
7154
7155 // 8-directional
7156 void enemy::newdir_8_old(int32_t newrate,int32_t newhoming,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2)
7157 {
7158 int32_t ndir=0;
7159
7160 // can move straight, check if it wants to turn
7161 if(canmove_old(dir,step,special,dx1,dy1,dx2,dy2))
7162 {
7163 if(grumble && (zc_oldrand()&4)<grumble) //Homing
7164 {
7165 int32_t w = Lwpns.idFirst(wBait);
7166
7167 if(w>=0)
7168 {
7169 int32_t bx = Lwpns.spr(w)->x;
7170 int32_t by = Lwpns.spr(w)->y;
7171
7172 ndir = (bx<x) ? left : (bx!=x) ? right : 0;
7173
7174 if(abs(int32_t(y)-by)>14)
7175 {
7176 if(ndir>0) // Already left or right
7177 {
7178 // Making the diagonal directions
7179 ndir += (by<y) ? 2 : 4;
7180 }
7181 else
7182 {
7183 ndir = (by<y) ? up : down;
7184 }
7185 }
7186
7187 if(canmove(ndir,special,false))
7188 {
7189 dir=ndir;
7190 return;
7191 }
7192 }
7193 }
7194
7195 // Homing added.
7196 if(newhoming && (zc_oldrand()&255)<newhoming)
7197 {
7198 ndir = lined_up(8,true);
7199
7200 if(ndir>=0 && canmove(ndir,special,false))
7201 {
7202 dir=ndir;
7203 }
7204
7205 return;
7206 }
7207
7208 int32_t r=zc_oldrand();
7209
7210 if(newrate>0 && !(r%newrate))
7211 {
7212 ndir = ((dir+((r&64)?-1:1))&7)+8;
7213 int32_t ndir2=((dir+((r&64)?1:-1))&7)+8;
7214
7215 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7216 dir=ndir;
7217 else if(canmove(ndir2,step,special,dx1,dy1,dx2,dy2,false))
7218 dir=ndir2;
7219
7220 if(dir==ndir && (newrate>=4)) // newrate>=4, otherwise movement is biased toward upper-left
7221 // due to numerous lost fractional components. -L
7222 {
7223 x.doFloor();
7224 y.doFloor();
7225 }
7226 }
7227
7228 return;
7229 }
7230
7231 // can't move straight, must turn
7232 int32_t i=0;
7233
7234 for(; i<32; i++) // Try random dir
7235 {
7236 ndir=(zc_oldrand()&7)+8;
7237
7238 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7239 break;
7240 }
7241
7242 if(i==32)
7243 {
7244 for(ndir=8; ndir<16; ndir++)
7245 {
7246 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7247 goto ok;
7248 }
7249
7250 ndir = (isSideViewGravity()) ? (zc_oldrand()&1 ? left : right) : -1; // Sideview enemies get trapped if their dir becomes -1
7251 }
7252
7253 ok:
7254 dir=ndir;
7255 x.doFloor();
7256 y.doFloor();
7257 }
7258
7259 3154 void enemy::newdir_8(int32_t newrate,int32_t newhoming,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2)
7260 {
7261 3154 int32_t ndir=0;
7262
7263 // can move straight, check if it wants to turn
7264
2/2
✓ Branch 0 taken 3018 times.
✓ Branch 1 taken 136 times.
3154 if(canmove(dir,step,special,dx1,dy1,dx2,dy2,false))
7265 {
7266
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3018 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3018 if(grumble && (zc_oldrand()&4)<abs(grumble)) //Homing
7267 {
7268 int32_t i = Lwpns.idFirst(wBait);
7269 if(i >= 0) //idfirst returns -1 if it can't find any
7270 {
7271 weapon *w = (weapon*)Lwpns.spr(i);
7272 if (get_bit(quest_rules, qr_FIND_CLOSEST_BAIT))
7273 {
7274 int32_t currentrange;
7275 if (distance(x, y, w->x, w->y) < w->misc2 || w->misc2 == 0) currentrange = distance(x, y, w->x, w->y);
7276 else currentrange = -1;
7277 int curid = i;
7278 ++i; //increment beforehand cause we just checked the first bait weapon and all others must be after it. ...otherwise it wouldn't be the first. -Deedee
7279 for(; i<Lwpns.Count(); ++i)
7280 {
7281 weapon *lw = (weapon*)Lwpns.spr(i);
7282 if (lw->id == wBait && distance(x, y, lw->x, lw->y) < currentrange && (distance(x, y, lw->x, lw->y) < lw->misc2 || lw->misc2 == 0))
7283 {
7284 currentrange = distance(x, y, lw->x, lw->y);
7285 curid = i;
7286 }
7287 }
7288 i = curid;
7289 if (currentrange == -1) i = -1;
7290 }
7291 else
7292 {
7293 if (!(distance(x, y, w->x, w->y) < w->misc2 || w->misc2 == 0)) i = -1;
7294 }
7295 if(i>=0)
7296 {
7297 int32_t bx = Lwpns.spr(i)->x;
7298 int32_t by = Lwpns.spr(i)->y;
7299
7300 ndir = (bx<x) ? left : (bx!=x) ? right : 0;
7301
7302 if(abs(int32_t(y)-by)>14)
7303 {
7304 if(ndir>0) // Already left or right
7305 {
7306 // Making the diagonal directions
7307 ndir += (by<y) ? 2 : 4;
7308 }
7309 else
7310 {
7311 ndir = (by<y) ? up : down;
7312 }
7313 }
7314 if (grumble < 0 || (itemsbuf[((weapon*)Lwpns.spr(i))->parentitem].flags & ITEM_FLAG1)) ndir = oppositeDir[ndir];
7315 if(canmove(ndir,special,false))
7316 {
7317 dir=ndir;
7318 return;
7319 }
7320 }
7321 }
7322 }
7323
7324 // Homing added.
7325
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3018 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3018 if(newhoming && (zc_oldrand()&255)<abs(newhoming))
7326 {
7327 ndir = lined_up(8,true);
7328 if (newhoming < 0 && ndir >= 0) ndir = oppositeDir[ndir];
7329 if(ndir>=0 && canmove(ndir,special,false))
7330 {
7331 dir=ndir;
7332 }
7333
7334 return;
7335 }
7336
7337 3018 int32_t r=zc_oldrand();
7338
7339
4/4
✓ Branch 0 taken 1438 times.
✓ Branch 1 taken 1580 times.
✓ Branch 2 taken 776 times.
✓ Branch 3 taken 662 times.
3018 if(newrate>0 && !(r%newrate))
7340 {
7341 662 ndir = ((dir+((r&64)?-1:1))&7)+8;
7342 662 int32_t ndir2=((dir+((r&64)?1:-1))&7)+8;
7343
7344
2/2
✓ Branch 0 taken 652 times.
✓ Branch 1 taken 10 times.
662 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7345 652 dir=ndir;
7346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 else if(canmove(ndir2,step,special,dx1,dy1,dx2,dy2,false))
7347 10 dir=ndir2;
7348
7349
3/4
✓ Branch 0 taken 652 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 652 times.
✗ Branch 3 not taken.
662 if(dir==ndir && (newrate>=4)) // newrate>=4, otherwise movement is biased toward upper-left
7350 // due to numerous lost fractional components. -L
7351 {
7352 x.doFloor();
7353 y.doFloor();
7354 }
7355 662 }
7356
7357 3018 return;
7358 }
7359
7360 // can't move straight, must turn
7361 136 int32_t i=0;
7362
7363
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 260 times.
260 for(; i<32; i++) // Try random dir
7364 {
7365 260 ndir=(zc_oldrand()&7)+8;
7366
7367
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 136 times.
260 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7368 136 break;
7369 124 }
7370
7371
1/2
✓ Branch 0 taken 136 times.
✗ Branch 1 not taken.
136 if(i==32)
7372 {
7373 for(ndir=8; ndir<16; ndir++)
7374 {
7375 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7376 goto ok;
7377 }
7378
7379 ndir = (isSideViewGravity()) ? (zc_oldrand()&1 ? left : right) : -1; // Sideview enemies get trapped if their dir becomes -1
7380 }
7381
7382 ok:
7383 136 dir=ndir;
7384 136 x.doFloor();
7385 136 y.doFloor();
7386 3154 }
7387
7388 3154 void enemy::newdir_8(int32_t newrate,int32_t newhoming,int32_t special)
7389 {
7390 3154 newdir_8(newrate,newhoming,special,0,-8,15,15);
7391 3154 }
7392
7393 void enemy::newdir_8_old(int32_t newrate,int32_t newhoming,int32_t special)
7394 {
7395 newdir_8_old(newrate,newhoming,special,0,-8,15,15);
7396 }
7397
7398 // makes the enemy slide backwards when hit
7399 // sclk: first byte is clk, second byte is dir
7400 // makes the enemy slide backwards when hit
7401 // sclk: first byte is clk, second byte is dir
7402 75502 int32_t enemy::slide()
7403 {
7404
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 75502 times.
75502 if(script_knockback_clk!=0) //scripted knockback
7405 {
7406 sclk = 0;
7407 return 1; //scripted knockback ran
7408 }
7409
5/6
✓ Branch 0 taken 722 times.
✓ Branch 1 taken 74780 times.
✓ Branch 2 taken 105 times.
✓ Branch 3 taken 617 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 105 times.
75502 if(sclk==0 || (hp<=0 && !immortal))
7410 74885 return 0;
7411
7412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 617 times.
617 if(knockbackflags & FLAG_NOSLIDE)
7413 {
7414 sclk = 0;
7415 if(!OFFGRID_ENEMY)
7416 {
7417 //Fix to grid
7418 //x = (int32_t(x)+8)-((int32_t(x)+8)%16);
7419 //y = (int32_t(y)+8)-((int32_t(y)+8)%16);
7420 do_fix(x, 16, true);
7421 do_fix(y, 16, true);
7422 }
7423 return 0;
7424 }
7425
5/10
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 548 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 69 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 50 times.
✓ Branch 7 taken 19 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
617 if((sclk&255)==16 && (get_bit(quest_rules,qr_OLD_ENEMY_KNOCKBACK_COLLISION) || knockbackSpeed!=4 ? !canmove(sclk>>8,(zfix) (dmisc2==e2tSPLITHIT ? 1 : 12),0,true) : !canmove(sclk>>8,(zfix) (dmisc2==e2tSPLITHIT ? 1 : knockbackSpeed),0,0,0,15,15,true)))
7426 {
7427 19 sclk=0;
7428 19 return 0;
7429 }
7430
7431 598 --sclk;
7432
7433
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 249 times.
✓ Branch 4 taken 279 times.
598 switch(sclk>>8)
7434 {
7435 case up:
7436 {
7437
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
49 if(y<=(dmisc2==e2tSPLITHIT ? 0 : (get_bit(quest_rules,qr_OLD_ENEMY_KNOCKBACK_COLLISION)?16:0))) //vires
7438 {
7439 sclk=0;
7440 return 0;
7441 }
7442
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
49 if ( dmisc2==e2tSPLITHIT && !canmove(sclk>>8,(zfix)(4),0,true) ) { sclk=0; return 0; } //vires
7443
7444 49 break;
7445 }
7446 case down:
7447 {
7448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if(y>=(dmisc2==e2tSPLITHIT ? 150 : 160)) //was 160 --changed for vires bug.
7449 {
7450 sclk=0;
7451 return 0;
7452 }
7453
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
21 if ( dmisc2==e2tSPLITHIT && !canmove(sclk>>8,(zfix)(4),0,true) ) { sclk=0; return 0; } //vires
7454
7455 21 break;
7456 }
7457 case left:
7458 {
7459
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 249 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 249 times.
249 if(x<=(dmisc2==e2tSPLITHIT ? 0 : (get_bit(quest_rules,qr_OLD_ENEMY_KNOCKBACK_COLLISION)?16:0)))
7460 {
7461 sclk=0;
7462 return 0;
7463 }
7464
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 249 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
249 if ( dmisc2==e2tSPLITHIT && !canmove(sclk>>8,(zfix)(4),0,true) ) { sclk=0; return 0; }
7465
7466 249 break;
7467 }
7468 case right:
7469 {
7470
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
279 if(x>=(dmisc2==e2tSPLITHIT ? 255 : 240)) //vires
7471 {
7472 sclk=0;
7473 return 0;
7474 }
7475
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
279 if ( dmisc2==e2tSPLITHIT && !canmove(sclk>>8,(zfix)(4),0,true) ) { sclk=0; return 0; } //vires
7476 279 break;
7477 }
7478 }
7479
7480 598 int32_t move = knockbackSpeed;
7481
2/2
✓ Branch 0 taken 567 times.
✓ Branch 1 taken 598 times.
1165 while(move>0)
7482 {
7483
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 598 times.
598 int32_t thismove = zc_min(8, move);
7484 598 move -= thismove;
7485 598 hitdir = (sclk>>8);
7486
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 249 times.
✓ Branch 4 taken 279 times.
598 switch(sclk>>8)
7487 {
7488 case up:
7489 49 y-=thismove;
7490 49 break;
7491
7492 case down:
7493 21 y+=thismove;
7494 21 break;
7495
7496 case left:
7497 249 x-=thismove;
7498 249 break;
7499
7500 case right:
7501 279 x+=thismove;
7502 279 break;
7503 }
7504
2/2
✓ Branch 0 taken 567 times.
✓ Branch 1 taken 31 times.
598 if(!canmove(sclk>>8,(zfix)0,0,true))
7505 {
7506
2/3
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
31 switch(sclk>>8)
7507 {
7508 case up:
7509 case down:
7510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if(y < 0)
7511 y = 0;
7512
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
8 else if((int32_t(y)&15) > 7)
7513 3 y=(int32_t(y)&0xF0)+16;
7514 else
7515 5 y=(int32_t(y)&0xF0);
7516
7517 8 break;
7518
7519 case left:
7520 case right:
7521
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if(x < 0)
7522 x = 0;
7523
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 16 times.
23 else if((int32_t(x)&15) > 7)
7524 7 x=(int32_t(x)&0xF0)+16;
7525 else
7526 16 x=(int32_t(x)&0xF0);
7527
7528 23 break;
7529 }
7530
7531 31 sclk=0;
7532 31 clk3=0;
7533 31 break;
7534 }
7535 }
7536
7537
2/2
✓ Branch 0 taken 549 times.
✓ Branch 1 taken 49 times.
598 if((sclk&255)==0)
7538 {
7539 //hitdir = -1;
7540 49 sclk=0;
7541 49 }
7542 598 return 2;
7543 75502 }
7544
7545 bool enemy::can_slide()
7546 {
7547 if(sclk==0 || (hp<=0 && !immortal))
7548 return false;
7549
7550 if((sclk&255)==16 && (get_bit(quest_rules,qr_OLD_ENEMY_KNOCKBACK_COLLISION) || knockbackSpeed!=4 ? !canmove(sclk>>8,(zfix) (dmisc2==e2tSPLITHIT ? 1 : 12),0,true) : !canmove(sclk>>8,(zfix) (dmisc2==e2tSPLITHIT ? 1 : knockbackSpeed),0,true)))
7551 {
7552 return false;
7553 }
7554
7555 return true;
7556 }
7557
7558 bool enemy::fslide()
7559 {
7560 if(sclk==0 || (hp<=0 && !immortal))
7561 return false;
7562
7563 if((sclk&255)==16 && !canmove(sclk>>8,(zfix)12,spw_floater,true))
7564 {
7565 sclk=0;
7566 return false;
7567 }
7568
7569 --sclk;
7570
7571 switch(sclk>>8)
7572 {
7573 case up:
7574 if(y<=16)
7575 {
7576 sclk=0;
7577 return false;
7578 }
7579
7580 break;
7581
7582 case down:
7583 if(y>=160)
7584 {
7585 sclk=0;
7586 return false;
7587 }
7588
7589 break;
7590
7591 case left:
7592 if(x<=16)
7593 {
7594 sclk=0;
7595 return false;
7596 }
7597
7598 break;
7599
7600 case right:
7601 if(x>=240)
7602 {
7603 sclk=0;
7604 return false;
7605 }
7606
7607 break;
7608 }
7609 hitdir = (sclk>>8);
7610 switch(sclk>>8)
7611 {
7612 case up:
7613 y-=4;
7614 break;
7615
7616 case down:
7617 y+=4;
7618 break;
7619
7620 case left:
7621 x-=4;
7622 break;
7623
7624 case right:
7625 x+=4;
7626 break;
7627 }
7628
7629 if(!canmove(sclk>>8,(zfix)0,spw_floater,true))
7630 {
7631 switch(sclk>>8)
7632 {
7633 case up:
7634 case down:
7635 if((int32_t(y)&15) > 7)
7636 y=(int32_t(y)&0xF0)+16;
7637 else
7638 y=(int32_t(y)&0xF0);
7639
7640 break;
7641
7642 case left:
7643 case right:
7644 if((int32_t(x)&15) > 7)
7645 x=(int32_t(x)&0xF0)+16;
7646 else
7647 x=(int32_t(x)&0xF0);
7648
7649 break;
7650 }
7651
7652 sclk=0;
7653 clk3=0;
7654 }
7655
7656 if((sclk&255)==0)
7657 sclk=0;
7658
7659 return true;
7660 }
7661
7662 bool enemy::knockback(int32_t time, int32_t dir, int32_t speed)
7663 {
7664 if((hp<=0 && !immortal)) return false; //No knocking back dead/mid-knockback enemies
7665 if(!canmove(dir,(zfix)speed,0,0,0,15,15,true)) return false; //from slide(); collision check
7666 bool ret = sprite::knockback(time, dir, speed);
7667 if(ret) sclk = 0; //kill engine knockback if interrupted
7668 //! Perhaps also set hitdir here, if needed for timing? -Z
7669 return ret;
7670 }
7671
7672 138890 bool enemy::runKnockback()
7673 {
7674
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 138890 times.
138890 if((script_knockback_clk&0xFF)==0)
7675 {
7676 138890 script_knockback_clk = 0;
7677 138890 return false;
7678 }
7679 if(knockbackflags & FLAG_NOSCRIPTKNOCKBACK)
7680 {
7681 return false;
7682 }
7683 int32_t move = script_knockback_speed;
7684 int32_t kb_dir = script_knockback_clk>>8;
7685 --script_knockback_clk;
7686
7687 while(move>0)
7688 {
7689 int32_t thismove = zc_min(get_bit(quest_rules, qr_OLD_SCRIPTED_KNOCKBACK)?8:4, move);
7690 move -= thismove;
7691 hitdir = kb_dir;
7692 switch(kb_dir)
7693 {
7694 case r_up:
7695 case l_up:
7696 case up:
7697 y-=thismove;
7698 break;
7699
7700 case r_down:
7701 case l_down:
7702 case down:
7703 y+=thismove;
7704 break;
7705 }
7706 switch(kb_dir)
7707 {
7708 case l_up:
7709 case l_down:
7710 case left:
7711 x-=thismove;
7712 break;
7713
7714 case r_up:
7715 case r_down:
7716 case right:
7717 x+=thismove;
7718 break;
7719 }
7720 if (get_bit(quest_rules, qr_OLD_SCRIPTED_KNOCKBACK))
7721 {
7722 if(!canmove(kb_dir,(zfix)0,0,true))
7723 {
7724 script_knockback_clk=0;
7725 clk3=0;
7726 //Fix to grid
7727 switch(kb_dir)
7728 {
7729 case up:
7730 case down:
7731 break;
7732 default:
7733 if(x < 0)
7734 x = 0;
7735 else if((int32_t(x)&15) > 7)
7736 x=(int32_t(x)&0xF0)+16;
7737 else
7738 x=(int32_t(x)&0xF0);
7739 break;
7740 }
7741 switch(kb_dir)
7742 {
7743 case left:
7744 case right:
7745 break;
7746 default:
7747 if(y < 0)
7748 y = 0;
7749 else if((int32_t(y)&15) > 7)
7750 y=(int32_t(y)&0xF0)+16;
7751 else
7752 y=(int32_t(y)&0xF0);
7753 break;
7754 }
7755 break;
7756 }
7757 }
7758 else
7759 {
7760 if(!scr_canplace(x,y,0,true))
7761 {
7762 script_knockback_clk=0;
7763 clk3=0;
7764 //Fix to grid
7765 if (OFFGRID_ENEMY)
7766 {
7767 switch(kb_dir)
7768 {
7769 case up:
7770 case down:
7771 break;
7772 default:
7773 if(x < 0)
7774 x = 0;
7775 else if((int32_t(x)&7) > 3)
7776 x=(int32_t(x)&0xF8)+8;
7777 else
7778 x=(int32_t(x)&0xF8);
7779 break;
7780 }
7781 switch(kb_dir)
7782 {
7783 case left:
7784 case right:
7785 break;
7786 default:
7787 if(y < 0)
7788 y = 0;
7789 else if((int32_t(y)&7) > 3)
7790 y=(int32_t(y)&0xF8)+8;
7791 else
7792 y=(int32_t(y)&0xF8);
7793 break;
7794 }
7795 }
7796 else
7797 {
7798 switch(kb_dir)
7799 {
7800 case up:
7801 case down:
7802 break;
7803 default:
7804 if(x < 0)
7805 x = 0;
7806 else if((int32_t(x)&15) > 7)
7807 x=(int32_t(x)&0xF0)+16;
7808 else
7809 x=(int32_t(x)&0xF0);
7810 break;
7811 }
7812 switch(kb_dir)
7813 {
7814 case left:
7815 case right:
7816 break;
7817 default:
7818 if(y < 0)
7819 y = 0;
7820 else if((int32_t(y)&15) > 7)
7821 y=(int32_t(y)&0xF0)+16;
7822 else
7823 y=(int32_t(y)&0xF0);
7824 break;
7825 }
7826 }
7827 break;
7828 }
7829
7830 }
7831 }
7832 return true;
7833 138890 }
7834 // changes enemy's direction, checking restrictions
7835 // rate: 0 = no random changes, 16 = always random change
7836 // homing: 0 = none, 256 = always
7837 // grumble 0 = none, 4 = strongest appetite
7838 2335 void enemy::newdir(int32_t newrate,int32_t newhoming,int32_t special)
7839 {
7840 2335 int32_t ndir=-1;
7841
7842
4/4
✓ Branch 0 taken 1199 times.
✓ Branch 1 taken 1136 times.
✓ Branch 2 taken 615 times.
✓ Branch 3 taken 584 times.
2335 if(grumble != 0 && (zc_oldrand()&3)<abs(grumble)) //yes, I know checking if grumble is equal to if grumble == 0, but the latter makes the intention more clear to less experienced coders who might join.
7843 {
7844 584 int32_t i = Lwpns.idFirst(wBait);
7845
1/2
✓ Branch 0 taken 584 times.
✗ Branch 1 not taken.
584 if(i >= 0) //idfirst returns -1 if it can't find any
7846 {
7847 weapon *w = (weapon*)Lwpns.spr(i);
7848 if (get_bit(quest_rules, qr_FIND_CLOSEST_BAIT))
7849 {
7850 int32_t currentrange;
7851 if (distance(x, y, w->x, w->y) < w->misc2 || w->misc2 == 0) currentrange = distance(x, y, w->x, w->y);
7852 else currentrange = -1;
7853 int curid = i;
7854 ++i; //increment beforehand cause we just checked the first bait weapon and all others must be after it. ...otherwise it wouldn't be the first. -Deedee
7855 for(; i<Lwpns.Count(); ++i)
7856 {
7857 weapon *lw = (weapon*)Lwpns.spr(i);
7858 if (lw->id == wBait && distance(x, y, lw->x, lw->y) < currentrange && (distance(x, y, lw->x, lw->y) < lw->misc2 || lw->misc2 == 0))
7859 {
7860 currentrange = distance(x, y, lw->x, lw->y);
7861 curid = i;
7862 }
7863 }
7864 i = curid;
7865 if (currentrange == -1) i = -1;
7866 }
7867 else
7868 {
7869 if (!(distance(x, y, w->x, w->y) < w->misc2 || w->misc2 == 0)) i = -1;
7870 }
7871 if (i >= 0)
7872 {
7873 int32_t bx = Lwpns.spr(i)->x;
7874 int32_t by = Lwpns.spr(i)->y;
7875
7876 if(abs(int32_t(y)-by)>14)
7877 {
7878 ndir = (by<y) ? up : down;
7879 if (grumble < 0 || (itemsbuf[((weapon*)Lwpns.spr(i))->parentitem].flags & ITEM_FLAG1)) ndir = oppositeDir[ndir];
7880 if(canmove(ndir,special,false))
7881 {
7882 dir=ndir;
7883 return;
7884 }
7885 }
7886
7887 ndir = (bx<x) ? left : right;
7888 if (grumble < 0 || (itemsbuf[((weapon*)Lwpns.spr(i))->parentitem].flags & ITEM_FLAG1)) ndir = oppositeDir[ndir];
7889 if(canmove(ndir,special,false))
7890 {
7891 dir=ndir;
7892 return;
7893 }
7894 }
7895 }
7896 584 }
7897
7898
2/2
✓ Branch 0 taken 1395 times.
✓ Branch 1 taken 940 times.
2335 if((zc_oldrand()&255)<abs(newhoming))
7899 {
7900 940 ndir = lined_up(8,false);
7901
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 940 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
940 if (newhoming < 0 && ndir >= 0) ndir = oppositeDir[ndir];
7902
4/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 685 times.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 230 times.
940 if(ndir>=0 && canmove(ndir,special,false))
7903 {
7904 230 dir=ndir;
7905 230 return;
7906 }
7907 710 }
7908
7909 2105 int32_t i=0;
7910
7911
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3908 times.
3909 for(; i<32; i++)
7912 {
7913 3908 int32_t r=zc_oldrand();
7914
7915
2/2
✓ Branch 0 taken 1198 times.
✓ Branch 1 taken 2710 times.
3908 if((r&15)<newrate)
7916 1198 ndir=(r>>4)&3;
7917 else
7918 2710 ndir=dir;
7919
7920
2/2
✓ Branch 0 taken 1804 times.
✓ Branch 1 taken 2104 times.
3908 if(canmove(ndir,special,false))
7921 2104 break;
7922 1804 }
7923
7924
2/2
✓ Branch 0 taken 2104 times.
✓ Branch 1 taken 1 times.
2105 if(i==32)
7925 {
7926
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 for(ndir=0; ndir<4; ndir++)
7927 {
7928
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(canmove(ndir,special,false))
7929 1 goto ok;
7930 1 }
7931
7932 ndir = (isSideViewGravity()) ? (zc_oldrand()&1 ? left : right) : -1; // Sideview enemies get trapped if their dir becomes -1
7933 //...Isn't that the point? I'm not sure I understand. Certainly beats phasing through walls... -Dimi
7934 }
7935
7936 ok:
7937 2105 dir = ndir;
7938 2335 }
7939
7940 void enemy::newdir()
7941 {
7942 newdir(4,0,spw_none);
7943 }
7944
7945 zfix enemy::distance_left()
7946 {
7947 int32_t a2=x.getInt();
7948 int32_t b2=y.getInt();
7949
7950 switch(dir)
7951 {
7952 case up:
7953 return (zfix)(b2&0xF);
7954
7955 case down:
7956 return (zfix)(16-(b2&0xF));
7957
7958 case left:
7959 return (zfix)(a2&0xF);
7960
7961 case right:
7962 return (zfix)(16-(a2&0xF));
7963 }
7964
7965 return (zfix)0;
7966 }
7967
7968 // keeps walking around
7969 void enemy::constant_walk(int32_t newrate,int32_t newhoming,int32_t special)
7970 {
7971 if(slide())
7972 return;
7973
7974 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock )
7975 return;
7976
7977 if(clk3<=0)
7978 {
7979 fix_coords(true);
7980 newdir(newrate,newhoming,special);
7981
7982 if(step==0)
7983 clk3=0;
7984 else
7985 clk3=int32_t(16.0/step);
7986 }
7987 else if(scored)
7988 {
7989 dir^=1;
7990 if (step != 0) clk3=int32_t(16.0/step)-clk3;
7991 else clk3=32767;
7992 }
7993
7994 if (step != 0) --clk3;
7995 move(step);
7996 }
7997
7998 void enemy::constant_walk()
7999 {
8000 constant_walk(4,0,spw_none);
8001 }
8002
8003 int32_t enemy::pos(int32_t newx,int32_t newy)
8004 {
8005 return (newy<<8)+newx;
8006 }
8007
8008 // for variable step rates
8009 void enemy::variable_walk(int32_t newrate,int32_t newhoming,int32_t special)
8010 {
8011 if(slide())
8012 return;
8013
8014 if(clk<0 || dying || stunclk || watch || step == 0 || ceiling || frozenclock )
8015 return;
8016
8017 zfix dx = (zfix)0;
8018 zfix dy = (zfix)0;
8019
8020 switch(dir)
8021 {
8022 case 8:
8023 case up:
8024 dy-=step;
8025 break;
8026
8027 case 12:
8028 case down:
8029 dy+=step;
8030 break;
8031
8032 case 14:
8033 case left:
8034 dx-=step;
8035 break;
8036
8037 case 10:
8038 case right:
8039 dx+=step;
8040 break;
8041
8042 case 15:
8043 case l_up:
8044 dx-=step;
8045 dy-=step;
8046 break;
8047
8048 case 9:
8049 case r_up:
8050 dx+=step;
8051 dy-=step;
8052 break;
8053
8054 case 13:
8055 case l_down:
8056 dx-=step;
8057 dy+=step;
8058 break;
8059
8060 case 11:
8061 case r_down:
8062 dx+=step;
8063 dy+=step;
8064 break;
8065 }
8066
8067 if(((int32_t(x)&15)==0 && (int32_t(y)&15)==0 && clk3!=pos(x,y)) ||
8068 m_walkflag(int32_t(x+dx),int32_t(y+dy), spw_halfstep, dir))
8069 {
8070 fix_coords();
8071 newdir(newrate,newhoming,special);
8072 clk3=pos(x,y);
8073 }
8074
8075 move(step);
8076 }
8077
8078 // pauses for a while after it makes a complete move (to a new square)
8079 71962 void enemy::halting_walk(int32_t newrate,int32_t newhoming,int32_t special,int32_t newhrate, int32_t haltcnt)
8080 {
8081
4/4
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 71290 times.
✓ Branch 2 taken 490 times.
✓ Branch 3 taken 182 times.
71962 if(sclk && clk2)
8082 {
8083 182 clk3=0;
8084 182 }
8085
8086
9/14
✓ Branch 0 taken 71395 times.
✓ Branch 1 taken 567 times.
✓ Branch 2 taken 71395 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 71395 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 68144 times.
✓ Branch 7 taken 3251 times.
✓ Branch 8 taken 68144 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 68144 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 68144 times.
71962 if(slide() || clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8087 {
8088 3818 return;
8089 }
8090
8091
2/2
✓ Branch 0 taken 16296 times.
✓ Branch 1 taken 51848 times.
68144 if(clk2>0)
8092 {
8093 16296 --clk2;
8094 16296 return;
8095 }
8096
8097
2/2
✓ Branch 0 taken 2333 times.
✓ Branch 1 taken 49515 times.
51848 if(clk3<=0)
8098 {
8099 2333 fix_coords(true);
8100 2333 newdir(newrate,newhoming,special);
8101 2333 clk3=int32_t(16.0/step);
8102
1/2
✓ Branch 0 taken 2333 times.
✗ Branch 1 not taken.
2333 if (step == 0) clk3 = 32767; //It used to return this in 2.53 and I'm unsure why; I'm guessing dividing by 0 gave max int? Either way, can't be 0 here or scripts break.
8103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2333 times.
2333 if(clk2<0)
8104 {
8105 clk2=0;
8106 }
8107
2/2
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 1875 times.
2333 else if((zc_oldrand()&15)<newhrate)
8108 {
8109 458 clk2=haltcnt;
8110 458 return;
8111 }
8112 1875 }
8113
2/2
✓ Branch 0 taken 49503 times.
✓ Branch 1 taken 12 times.
49515 else if(scored)
8114 {
8115 12 dir^=1;
8116
8117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (step != 0) clk3=int32_t(16.0/step)-clk3;
8118 else clk3=32767;
8119 12 }
8120
8121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51390 times.
51390 if (step != 0) --clk3;
8122 51390 move(step);
8123 71962 }
8124
8125 // 8-directional movement, aligns to 8 pixels
8126 void enemy::constant_walk_8(int32_t newrate,int32_t newhoming,int32_t special)
8127 {
8128 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8129 return;
8130
8131 if(clk3<=0)
8132 {
8133 newdir_8(newrate,newhoming,special);
8134 clk3=int32_t(8.0/step);
8135 if (step == 0) clk3 = 32767;
8136 }
8137
8138 if (step != 0) --clk3;
8139 move(step);
8140 }
8141 // 8-directional movement, aligns to 8 pixels
8142 void enemy::constant_walk_8_old(int32_t newrate,int32_t newhoming,int32_t special)
8143 {
8144 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8145 return;
8146
8147 if(clk3<=0)
8148 {
8149 newdir_8(newrate,newhoming,special);
8150 clk3=int32_t(8.0/step);
8151 if (step == 0) clk3 = 32767;
8152 }
8153
8154 if (step != 0) --clk3;
8155 move(step);
8156 }
8157
8158 void enemy::halting_walk_8(int32_t newrate,int32_t newhoming, int32_t newclk,int32_t special,int32_t newhrate, int32_t haltcnt)
8159 {
8160 if(clk<0 || dying || stunclk || watch || frozenclock)
8161 return;
8162
8163 if(!canmove(dir,step,special,false))
8164 clk3=0;
8165
8166 if(clk2>0)
8167 {
8168 --clk2;
8169 return;
8170 }
8171
8172 if(clk3<=0)
8173 {
8174 newdir_8(newrate,newhoming,special);
8175 clk3=newclk;
8176
8177 if(clk2<0)
8178 {
8179 clk2=0;
8180 }
8181 else if((zc_oldrand()&15)<newhrate)
8182 {
8183 newdir_8(newrate,newhoming,special);
8184 clk2=haltcnt;
8185 return;
8186 }
8187 }
8188
8189 --clk3;
8190 move(step);
8191 }
8192
8193 // 8-directional movement, no alignment
8194 26061 void enemy::variable_walk_8(int32_t newrate,int32_t newhoming, int32_t newclk,int32_t special)
8195 {
8196
7/12
✓ Branch 0 taken 24519 times.
✓ Branch 1 taken 1542 times.
✓ Branch 2 taken 24519 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24519 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 24519 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 24519 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 24519 times.
26061 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8197 1542 return;
8198
8199
2/2
✓ Branch 0 taken 24383 times.
✓ Branch 1 taken 136 times.
24519 if(!canmove(dir,step,special,false))
8200 136 clk3=0;
8201
8202
2/2
✓ Branch 0 taken 21365 times.
✓ Branch 1 taken 3154 times.
24519 if(clk3<=0)
8203 {
8204 3154 newdir_8(newrate,newhoming,special);
8205 3154 clk3=newclk;
8206 3154 }
8207
8208 24519 --clk3;
8209 24519 move(step);
8210 26061 }
8211
8212 // same as above but with variable enemy size
8213 void enemy::variable_walk_8(int32_t newrate,int32_t newhoming, int32_t newclk,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2)
8214 {
8215 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8216 return;
8217
8218 if(!canmove(dir,step,special,dx1,dy1,dx2,dy2,false))
8219 clk3=0;
8220
8221 if(clk3<=0)
8222 {
8223 newdir_8(newrate,newhoming,special,dx1,dy1,dx2,dy2);
8224 clk3=newclk;
8225 }
8226
8227 --clk3;
8228 move(step);
8229 }
8230
8231 // the variable speed floater movement
8232 // ms is max speed
8233 // ss is step speed
8234 // s is step count
8235 // p is pause count
8236 // g is graduality :)
8237 //floater_walk(rate,hrate,dstep/100,(zfix)0,10,dmisc16,dmisc17);
8238 23060 void enemy::floater_walk(int32_t newrate,int32_t newclk,zfix ms,zfix ss,int32_t s,int32_t p, int32_t g)
8239 {
8240 23060 ++clk2;
8241 23060 byte over_pit = overpit(this);
8242
8243
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 23060 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
23060 if(dmisc1 && over_pit) p = 0;
8244
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 715 times.
✓ Branch 2 taken 12004 times.
✓ Branch 3 taken 8833 times.
✓ Branch 4 taken 1508 times.
23060 switch(movestatus)
8245 {
8246 //! This needs a case 4 (landing)....if we want to halt, we move to case 4, and
8247 //! if the conditions prevent it, we jump back to case 2.
8248 case 0: // paused
8249
2/2
✓ Branch 0 taken 711 times.
✓ Branch 1 taken 4 times.
715 if(clk2>=p)
8250 {
8251 4 movestatus=1;
8252 4 clk2=0;
8253 4 }
8254
8255 715 break;
8256
8257 case 1: // speeding up
8258
1/2
✓ Branch 0 taken 12004 times.
✗ Branch 1 not taken.
12004 if (s >= 0)
8259 {
8260
2/2
✓ Branch 0 taken 11948 times.
✓ Branch 1 taken 56 times.
12004 if(clk2<g*s)
8261 {
8262
2/2
✓ Branch 0 taken 11182 times.
✓ Branch 1 taken 766 times.
11948 if(!((clk2-1)%g))
8263 766 step+=ss;
8264 11948 }
8265 else
8266 {
8267 56 movestatus=2;
8268 56 clk2=0;
8269 }
8270 12004 }
8271 else
8272 {
8273 if(step < ms)
8274 {
8275 if(!((clk2-1)%g))
8276 {
8277 step+=ss;
8278 if (step >= ms) step = ms;
8279 }
8280 }
8281 else
8282 {
8283 step = ms;
8284 movestatus=2;
8285 clk2=0;
8286 }
8287 }
8288
8289 12004 break;
8290
8291 case 2: // normal
8292 8833 step=ms;
8293
8294
6/8
✗ Branch 0 not taken.
✓ Branch 1 taken 8833 times.
✓ Branch 2 taken 2136 times.
✓ Branch 3 taken 6697 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6697 times.
✓ Branch 6 taken 6685 times.
✓ Branch 7 taken 12 times.
8833 if(clk2>(dmisc15>0?dmisc15:48) && !(zc_oldrand()%(dmisc14>0?dmisc14:768)))
8295 {
8296
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (s >= 0) step=ss*s;
8297 else step=ms;
8298 12 movestatus=3;
8299 12 clk2=0;
8300 12 }
8301
8302 8833 break;
8303
8304 case 3: // slowing down
8305
1/2
✓ Branch 0 taken 1508 times.
✗ Branch 1 not taken.
1508 if (s >= 0)
8306 {
8307
2/2
✓ Branch 0 taken 1501 times.
✓ Branch 1 taken 7 times.
1508 if(clk2<=g*s)
8308 {
8309 { //don't slow down over pits
8310
8311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1501 times.
1501 if(over_pit)
8312 {
8313 if(dmisc1)
8314 {
8315 step=ms;
8316 }
8317 }
8318 else //can slow down
8319 {
8320
3/4
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 1410 times.
✓ Branch 2 taken 91 times.
✗ Branch 3 not taken.
1501 if(!(clk2%g) && !dmisc1)
8321 91 step-=ss;
8322 }
8323 }
8324
8325
8326 1501 }
8327 else
8328 {
8329 //if((moveflags&FLAG_CAN_PITFALL)) //don't check pits if the enemy ignores them
8330 //this doesn't help keese, as they have a z of 0.
8331 //they always nee to run this check.
8332 {
8333
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7 if(over_pit &&!dmisc1)
8334 {
8335 --clk2; //if over a pit, don't land, and revert clock change
8336 }
8337 else //can land safely
8338 {
8339 7 movestatus=0;
8340
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7 if(dmisc1&&!over_pit)
8341 step=0;
8342 7 clk2=0;
8343 }
8344 }
8345
8346 }
8347 1508 }
8348 else
8349 {
8350 if(step > 0)
8351 {
8352 if(over_pit)
8353 {
8354 if(dmisc1)
8355 {
8356 step=ms;
8357 }
8358 }
8359 else //can slow down
8360 {
8361 if(!(clk2%g))
8362 step-=ss;
8363 }
8364 }
8365 else
8366 {
8367 //if((moveflags&FLAG_CAN_PITFALL)) //don't check pits if the enemy ignores them
8368 //this doesn't help keese, as they have a z of 0.
8369 //they always nee to run this check.
8370 if(over_pit)
8371 {
8372 step+=ss; //if over a pit, don't land, and revert clock change
8373 }
8374 else //can land safely
8375 {
8376 movestatus=0;
8377 step=0;
8378 clk2=0;
8379 }
8380 }
8381 }
8382
8383 1508 break;
8384 }
8385
8386
2/2
✓ Branch 0 taken 8877 times.
✓ Branch 1 taken 14183 times.
23060 variable_walk_8(movestatus==2?newrate:0,homing,newclk,spw_floater);
8387 23060 }
8388
8389 void enemy::floater_walk(int32_t newrate,int32_t newclk,zfix s)
8390 {
8391 floater_walk(newrate,newclk,s,(zfix)0.125,3,80,32);
8392 }
8393
8394 // Checks if enemy is lined up with Hero. If so, returns direction Hero is
8395 // at as compared to enemy. Returns -1 if not lined up. Range is inclusive.
8396 940 int32_t enemy::lined_up(int32_t range, bool dir8)
8397 {
8398 940 int32_t lx = Hero.getX();
8399 940 int32_t ly = Hero.getY();
8400
8401
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 853 times.
940 if(abs(lx-int32_t(x))<=range)
8402 {
8403
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 35 times.
87 if(ly<y)
8404 {
8405 52 return up;
8406 }
8407
8408 35 return down;
8409 }
8410
8411
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 685 times.
853 if(abs(ly-int32_t(y))<=range)
8412 {
8413
2/2
✓ Branch 0 taken 107 times.
✓ Branch 1 taken 61 times.
168 if(lx<x)
8414 {
8415 107 return left;
8416 }
8417
8418 61 return right;
8419 }
8420
8421
1/2
✓ Branch 0 taken 685 times.
✗ Branch 1 not taken.
685 if(dir8)
8422 {
8423 if(abs(lx-x)-abs(ly-y)<=range)
8424 //if(abs(lx-x)-abs(ly-y)<=range && abs(ly-y)-abs(lx-x)<=range) //Fix floating enemies not seeking hero. -Tamamo
8425 {
8426 if(ly<y)
8427 {
8428 if(lx<x)
8429 {
8430 return l_up;
8431 }
8432 else
8433 {
8434 return r_up;
8435 }
8436 }
8437 else
8438 {
8439 if(lx<x)
8440 {
8441 return l_down;
8442 }
8443 else
8444 {
8445 return r_down;
8446 }
8447 }
8448 }
8449 }
8450
8451 685 return -1;
8452 940 }
8453
8454 // returns true if Hero is within 'range' pixels of the enemy
8455 3 bool enemy::HeroInRange(int32_t range)
8456 {
8457 3 int32_t lx = Hero.getX();
8458 3 int32_t ly = Hero.getY();
8459
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 return abs(lx-int32_t(x))<=range && abs(ly-int32_t(y))<=range;
8460 }
8461
8462 // place the enemy in line with Hero (red wizzrobes)
8463 void enemy::place_on_axis(bool floater, bool solid_ok)
8464 {
8465 int32_t lx=zc_min(zc_max(int32_t(Hero.getX())&0xF0,32),208);
8466 int32_t ly=zc_min(zc_max(int32_t(Hero.getY())&0xF0,32),128);
8467 int32_t pos2=zc_oldrand()%23;
8468 int32_t tried=0;
8469 bool last_resort,placed=false;
8470
8471
8472 do
8473 {
8474 if(pos2<14)
8475 {
8476 x=(pos2<<4)+16;
8477 y=ly;
8478 }
8479 else
8480 {
8481 x=lx;
8482 y=((pos2-14)<<4)+16;
8483 }
8484
8485 // Don't commit to a last resort if position is out of bounds.
8486 last_resort= !(x<32 || y<32 || x>=224 || y>=144);
8487
8488 if(abs(lx-int32_t(x))>16 || abs(ly-int32_t(y))>16)
8489 {
8490 // Red Wizzrobes should be able to appear on water, but not other
8491 // solid combos; however, they could appear on solid combos in 2.10,
8492 // and some quests depend on that.
8493 if((solid_ok || !m_walkflag(x,y,floater ? spw_water : spw_door, dir))
8494 && !flyerblocked(x,y,floater ? spw_floater : spw_door))
8495 placed=true;
8496 }
8497
8498 if(!placed && tried>=22 && last_resort)
8499 {
8500 placed=true;
8501 }
8502
8503 ++tried;
8504 pos2=(pos2+3)%23;
8505 }
8506 while(!placed);
8507
8508 if(y==ly)
8509 dir=(x<lx)?right:left;
8510 else
8511 dir=(y<ly)?down:up;
8512
8513 clk2=tried;
8514 }
8515
8516 89632 int32_t enemy::n_frame_n_dir(int32_t frames, int32_t ndir, int32_t f4)
8517 {
8518 89632 int32_t t = o_tile;
8519 89632 int32_t b = o_tile;
8520
8521 // Darknuts, but also Wizzrobes and Wallmasters
8522
2/4
✓ Branch 0 taken 39193 times.
✓ Branch 1 taken 50439 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
89632 switch(family)
8523 {
8524 case eeWALK:
8525
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 50439 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
50439 if(dmisc9==e9tPOLSVOICE && clk2>=0 && do_animation)
8526 {
8527 tile=s_tile;
8528 t=s_tile;
8529 b=s_tile;
8530 }
8531
8532 50439 break;
8533
8534 case eeTRAP:
8535 if(dummy_int[1] && guysbuf[id].flags2 & eneflag_trp2 && do_animation) // Just to make sure
8536 {
8537 tile=s_tile;
8538 t=s_tile;
8539 b=s_tile;
8540 }
8541
8542 break;
8543
8544 case eeSPINTILE:
8545 if(misc>=96 && do_animation)
8546 {
8547 tile=o_tile+frames*ndir;
8548 t=tile;
8549 }
8550
8551 break;
8552 }
8553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 89632 times.
89632 if ( do_animation )
8554 {
8555
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 89632 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 89632 times.
89632 if(ndir!=0) switch(frames)
8556 {
8557 case 2:
8558 tiledir_small(dir,ndir==4);
8559 break;
8560
8561 case 3:
8562 tiledir_three(dir);
8563 break;
8564
8565 case 4:
8566 89632 tiledir(dir,ndir==4);
8567 89632 break;
8568 89632 }
8569
8570
2/2
✓ Branch 0 taken 50439 times.
✓ Branch 1 taken 39193 times.
89632 if(family==eeWALK)
8571
6/6
✓ Branch 0 taken 39841 times.
✓ Branch 1 taken 10598 times.
✓ Branch 2 taken 37273 times.
✓ Branch 3 taken 13166 times.
✓ Branch 4 taken 10298 times.
✓ Branch 5 taken 2868 times.
50439 tile=zc_min(tile+f4, t+frames*(zc_max(dir, 0)+1)-1);
8572 else
8573 39193 tile+=f4;
8574 89632 }
8575 89632 return b;
8576 }
8577
8578 void enemy::tiledir_three(int32_t ndir)
8579 {
8580 if ( !do_animation ) return;
8581 flip=0;
8582
8583 switch(ndir)
8584 {
8585 case right:
8586 tile+=3;
8587 [[fallthrough]];
8588
8589 case left:
8590 tile+=3;
8591 [[fallthrough]];
8592
8593 case down:
8594 tile+=3;
8595 [[fallthrough]];
8596
8597 case up:
8598 break;
8599 }
8600 }
8601
8602 void enemy::tiledir_small(int32_t ndir, bool fourdir)
8603 {
8604 if ( !do_animation ) return;
8605 flip=0;
8606
8607 switch(ndir)
8608 {
8609 case 8:
8610 case up:
8611 break;
8612
8613 case 12:
8614 case down:
8615 tile+=2;
8616 break;
8617
8618 case 14:
8619 case left:
8620 tile+=4;
8621 break;
8622
8623 case 10:
8624 case right:
8625 tile+=6;
8626 break;
8627
8628 case 9:
8629 case r_up:
8630 if(fourdir)
8631 break;
8632
8633 tile+=10;
8634 break;
8635
8636 case 11:
8637 case r_down:
8638 if(fourdir)
8639 tile+=2;
8640 else
8641 tile+=14;
8642
8643 break;
8644
8645 case 13:
8646 case l_down:
8647 if(fourdir)
8648 tile+=2;
8649 else
8650 tile+=12;
8651
8652 break;
8653
8654 case 15:
8655 case l_up:
8656 if(fourdir)
8657 break;
8658
8659 tile+=8;
8660 break;
8661
8662 default:
8663 //dir=(zc_oldrand()*100)%8;
8664 //tiledir_small(dir);
8665 // flip=zc_oldrand()&3;
8666 // tile=(zc_oldrand()*100000)%NEWMAXTILES;
8667 break;
8668 }
8669 }
8670
8671 96321 void enemy::tiledir(int32_t ndir, bool fourdir)
8672 {
8673
1/2
✓ Branch 0 taken 96321 times.
✗ Branch 1 not taken.
96321 if ( !do_animation ) return;
8674 96321 flip=0;
8675
8676
8/9
✓ Branch 0 taken 19496 times.
✓ Branch 1 taken 15288 times.
✓ Branch 2 taken 19767 times.
✓ Branch 3 taken 21492 times.
✓ Branch 4 taken 5350 times.
✓ Branch 5 taken 6896 times.
✓ Branch 6 taken 5206 times.
✓ Branch 7 taken 2826 times.
✗ Branch 8 not taken.
96321 switch(ndir)
8677 {
8678 case 8:
8679 case up:
8680 19496 break;
8681
8682 case 12:
8683 case down:
8684 15288 tile+=4;
8685 15288 break;
8686
8687 case 14:
8688 case left:
8689 19767 tile+=8;
8690 19767 break;
8691
8692 case 10:
8693 case right:
8694 21492 tile+=12;
8695 21492 break;
8696
8697 case 9:
8698 case r_up:
8699
2/2
✓ Branch 0 taken 535 times.
✓ Branch 1 taken 4815 times.
5350 if(fourdir)
8700 535 break;
8701 else
8702 4815 tile+=24;
8703
8704 4815 break;
8705
8706 case 11:
8707 case r_down:
8708
2/2
✓ Branch 0 taken 870 times.
✓ Branch 1 taken 6026 times.
6896 if(fourdir)
8709 870 tile+=4;
8710 else
8711 6026 tile+=32;
8712
8713 6896 break;
8714
8715 case 13:
8716 case l_down:
8717
2/2
✓ Branch 0 taken 106 times.
✓ Branch 1 taken 5100 times.
5206 if(fourdir)
8718 106 tile+=4;
8719 else
8720 5100 tile+=28;
8721
8722 5206 break;
8723
8724 case 15:
8725 case l_up:
8726
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 2758 times.
2826 if(fourdir)
8727 68 break;
8728 else
8729 2758 tile+=20;
8730
8731 2758 break;
8732
8733 default:
8734 //dir=(zc_oldrand()*100)%8;
8735 //tiledir(dir);
8736 // flip=zc_oldrand()&3;
8737 // tile=(zc_oldrand()*100000)%NEWMAXTILES;
8738 break;
8739 }
8740 96321 }
8741
8742 void enemy::tiledir_big(int32_t ndir, bool fourdir)
8743 {
8744 if ( !do_animation ) return;
8745 flip=0;
8746
8747 switch(ndir)
8748 {
8749 case 8:
8750 case up:
8751 break;
8752
8753 case 12:
8754 case down:
8755 tile+=8;
8756 break;
8757
8758 case 14:
8759 case left:
8760 tile+=40;
8761 break;
8762
8763 case 10:
8764 case right:
8765 tile+=48;
8766 break;
8767
8768 case 9:
8769 case r_up:
8770 if(fourdir)
8771 break;
8772
8773 tile+=88;
8774 break;
8775
8776 case 11:
8777 case r_down:
8778 if(fourdir)
8779 tile+=8;
8780 else
8781 tile+=128;
8782
8783 break;
8784
8785 case 13:
8786 case l_down:
8787 if(fourdir)
8788 tile+=8;
8789 else
8790 tile+=120;
8791
8792 break;
8793
8794 case 15:
8795 case l_up:
8796 if(fourdir)
8797 break;
8798
8799 tile+=80;
8800 break;
8801
8802 default:
8803 //dir=(zc_oldrand()*100)%8;
8804 //tiledir_big(dir);
8805 // flip=zc_oldrand()&3;
8806 // tile=(zc_oldrand()*100000)%NEWMAXTILES;
8807 break;
8808 }
8809 }
8810
8811 177066 void enemy::update_enemy_frame()
8812 {
8813
2/4
✓ Branch 0 taken 177066 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 177066 times.
177066 if(fallclk||drownclk) return;
8814
1/2
✓ Branch 0 taken 177066 times.
✗ Branch 1 not taken.
177066 if (!do_animation)
8815 return;
8816
8817
3/4
✓ Branch 0 taken 9470 times.
✓ Branch 1 taken 167596 times.
✓ Branch 2 taken 9470 times.
✗ Branch 3 not taken.
177066 if (get_bit(quest_rules,qr_OLD_TILE_INITIALIZATION) || tile == 0) tile = o_tile; //tile was initialized here before. It needs to be initialized here as well.
8818
8819
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
177066 if(get_bit(quest_rules,qr_ANONE_NOANIM)
8820
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 177066 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
177066 && anim == aNONE && family != eeGUY)
8821 return;
8822
2/2
✓ Branch 0 taken 175965 times.
✓ Branch 1 taken 1101 times.
177066 int32_t newfrate = zc_max(frate,4);
8823 177066 int32_t f4=abs(clk/(newfrate/4)); // casts clk to [0,1,2,3]
8824 177066 int32_t f2=abs(clk/(newfrate/2)); // casts clk to [0,1]
8825
2/2
✓ Branch 0 taken 107573 times.
✓ Branch 1 taken 69493 times.
177066 int32_t fx = get_bit(quest_rules, qr_NEWENEMYTILES) ? f4 : f2;
8826 177066 tile = o_tile;
8827 177066 int32_t basetile = o_tile;
8828 177066 int32_t tilerows = 1; // How many rows of tiles? The Extend code needs to know.
8829 177066 bool ignore_extend = false;
8830
17/40
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16798 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 4548 times.
✓ Branch 7 taken 3737 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 5255 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1053 times.
✓ Branch 21 taken 2952 times.
✓ Branch 22 taken 16892 times.
✓ Branch 23 taken 3515 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 38388 times.
✓ Branch 27 taken 12051 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 9702 times.
✓ Branch 30 taken 9236 times.
✓ Branch 31 taken 884 times.
✓ Branch 32 taken 2677 times.
✓ Branch 33 taken 9464 times.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✓ Branch 36 taken 39193 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 721 times.
✗ Branch 39 not taken.
177066 switch(anim)
8831 {
8832
8833 case aDONGO:
8834 {
8835 int32_t fr = stunclk>0 ? 16 : 8;
8836
8837 if(!dying && clk2>0 && clk2<=64)
8838 {
8839 // bloated
8840 switch(dir)
8841 {
8842 case up:
8843 tile+=9;
8844 flip=0;
8845 xofs=0;
8846 dummy_int[1]=0; //no additional tiles
8847 break;
8848
8849 case down:
8850 tile+=7;
8851 flip=0;
8852 xofs=0;
8853 dummy_int[1]=0; //no additional tiles
8854 break;
8855
8856 case left:
8857 flip=1;
8858 tile+=4;
8859 xofs=16;
8860 dummy_int[1]=1; //second tile is next tile
8861 break;
8862
8863 case right:
8864 flip=0;
8865 tile+=5;
8866 xofs=16;
8867 dummy_int[1]=-1; //second tile is previous tile
8868 break;
8869 }
8870 }
8871 else if(!dying || clk2>19)
8872 {
8873 // normal
8874 switch(dir)
8875 {
8876 case up:
8877 tile+=8;
8878 flip=(clk&fr)?1:0;
8879 xofs=0;
8880 dummy_int[1]=0; //no additional tiles
8881 break;
8882
8883 case down:
8884 tile+=6;
8885 flip=(clk&fr)?1:0;
8886 xofs=0;
8887 dummy_int[1]=0; //no additional tiles
8888 break;
8889
8890 case left:
8891 flip=1;
8892 tile+=(clk&fr)?2:0;
8893 xofs=16;
8894 dummy_int[1]=1; //second tile is next tile
8895 break;
8896
8897 case right:
8898 flip=0;
8899 tile+=(clk&fr)?3:1;
8900 xofs=16;
8901 dummy_int[1]=-1; //second tile is next tile
8902 break;
8903 }
8904 }
8905 }
8906 break;
8907
8908 case aNEWDONGO:
8909 {
8910 int32_t fr4=0;
8911
8912 if(!dying && clk2>0 && clk2<=64)
8913 {
8914 // bloated
8915 if(clk2>=0)
8916 {
8917 fr4=3;
8918 }
8919
8920 if(clk2>=16)
8921 {
8922 fr4=2;
8923 }
8924
8925 if(clk2>=32)
8926 {
8927 fr4=1;
8928 }
8929
8930 if(clk2>=48)
8931 {
8932 fr4=0;
8933 }
8934
8935 switch(dir)
8936 {
8937 case up:
8938 xofs=0;
8939 tile+=8+fr4;
8940 dummy_int[1]=0; //no additional tiles
8941 break;
8942
8943 case down:
8944 xofs=0;
8945 tile+=12+fr4;
8946 dummy_int[1]=0; //no additional tiles
8947 break;
8948
8949 case left:
8950 tile+=29+(2*fr4);
8951 xofs=16;
8952 dummy_int[1]=-1; //second tile is previous tile
8953 break;
8954
8955 case right:
8956 tile+=49+(2*fr4);
8957 xofs=16;
8958 dummy_int[1]=-1; //second tile is previous tile
8959 break;
8960 }
8961 }
8962 else if(!dying || clk2>19)
8963 {
8964 // normal
8965 switch(dir)
8966 {
8967 case up:
8968 xofs=0;
8969 tile+=((clk&12)>>2);
8970 dummy_int[1]=0; //no additional tiles
8971 break;
8972
8973 case down:
8974 xofs=0;
8975 tile+=4+((clk&12)>>2);
8976 dummy_int[1]=0; //no additional tiles
8977 break;
8978
8979 case left:
8980 tile+=21+((clk&12)>>1);
8981 xofs=16;
8982 dummy_int[1]=-1; //second tile is previous tile
8983 break;
8984
8985 case right:
8986 flip=0;
8987 tile+=41+((clk&12)>>1);
8988 xofs=16;
8989 dummy_int[1]=-1; //second tile is previous tile
8990 break;
8991 }
8992 }
8993 }
8994 break;
8995
8996 case aDONGOBS:
8997 {
8998 int32_t fr4=0;
8999
9000 if(!dying && clk2>0 && clk2<=64)
9001 {
9002 // bloated
9003 if(clk2>=0)
9004 {
9005 fr4=3;
9006 }
9007
9008 if(clk2>=16)
9009 {
9010 fr4=2;
9011 }
9012
9013 if(clk2>=32)
9014 {
9015 fr4=1;
9016 }
9017
9018 if(clk2>=48)
9019 {
9020 fr4=0;
9021 }
9022
9023 switch(dir)
9024 {
9025 case up:
9026 tile+=28+fr4;
9027 yofs+=8;
9028 dummy_int[1]=-20; //second tile change
9029 dummy_int[2]=0; //new xofs change
9030 dummy_int[3]=-16; //new xofs change
9031 break;
9032
9033 case down:
9034 tile+=12+fr4;
9035 yofs-=8;
9036 dummy_int[1]=20; //second tile change
9037 dummy_int[2]=0; //new xofs change
9038 dummy_int[3]=16; //new xofs change
9039 break;
9040
9041 case left:
9042 tile+=49+(2*fr4);
9043 xofs+=8;
9044 dummy_int[1]=-1; //second tile change
9045 dummy_int[2]=-16; //new xofs change
9046 dummy_int[3]=0; //new xofs change
9047 break;
9048
9049 case right:
9050 tile+=69+(2*fr4);
9051 xofs+=8;
9052 dummy_int[1]=-1; //second tile change
9053 dummy_int[2]=-16; //new xofs change
9054 dummy_int[3]=0; //new xofs change
9055 break;
9056 }
9057 }
9058 else if(!dying || clk2>19)
9059 {
9060 // normal
9061 switch(dir)
9062 {
9063 case up:
9064 tile+=20+((clk&24)>>3);
9065 yofs+=8;
9066 dummy_int[1]=-20; //second tile change
9067 dummy_int[2]=0; //new xofs change
9068 dummy_int[3]=-16; //new xofs change
9069 break;
9070
9071 case down:
9072 tile+=4+((clk&24)>>3);
9073 yofs-=8;
9074 dummy_int[1]=20; //second tile change
9075 dummy_int[2]=0; //new xofs change
9076 dummy_int[3]=16; //new xofs change
9077 break;
9078
9079 case left:
9080 xofs=-8;
9081 tile+=40+((clk&24)>>2);
9082 dummy_int[1]=1; //second tile change
9083 dummy_int[2]=16; //new xofs change
9084 dummy_int[3]=0; //new xofs change
9085 break;
9086
9087 case right:
9088 tile+=60+((clk&24)>>2);
9089 xofs=-8;
9090 dummy_int[1]=1; //second tile change
9091 dummy_int[2]=16; //new xofs change
9092 dummy_int[3]=0; //new xofs change
9093 break;
9094 }
9095 }
9096 }
9097 break;
9098
9099 case aWIZZ:
9100 {
9101 // if(d->misc1)
9102 if(dmisc1)
9103 {
9104 if(clk&8)
9105 {
9106 ++tile;
9107 }
9108 }
9109 else
9110 {
9111 if(frame&4)
9112 {
9113 ++tile;
9114 }
9115 }
9116
9117 switch(dir)
9118 {
9119 case 9:
9120 case 15:
9121 case up:
9122 tile+=2;
9123 break;
9124
9125 case down:
9126 break;
9127
9128 case 13:
9129 case left:
9130 flip=1;
9131 break;
9132
9133 default:
9134 flip=0;
9135 break;
9136 }
9137 }
9138 break;
9139
9140 case aNEWWIZZ:
9141 {
9142 tiledir(dir,true);
9143
9144 // if(d->misc1) //walking wizzrobe
9145 if(dmisc1) //walking wizzrobe
9146 {
9147 if(clk&8)
9148 {
9149 tile+=2;
9150 }
9151
9152 if(clk&4)
9153 {
9154 tile+=1;
9155 }
9156
9157 if(!(dummy_bool[1]||dummy_bool[2])) //should never be charging or firing for these wizzrobes
9158 {
9159 if(dummy_int[1]>0)
9160 {
9161 tile+=40;
9162 }
9163 }
9164 }
9165 else
9166 {
9167 if(dummy_bool[1]||dummy_bool[2])
9168 {
9169 tile+=20;
9170
9171 if(dummy_bool[2])
9172 {
9173 tile+=20;
9174 }
9175 }
9176
9177 tile+=((frame>>1)&3);
9178 }
9179 }
9180 break;
9181
9182 case a3FRM:
9183 {
9184 basetile = n_frame_n_dir(3, 0, (f4==3) ? 1 : f4);
9185 }
9186 break;
9187
9188 case a3FRM4DIR:
9189 {
9190 basetile = n_frame_n_dir(3, 4, (f4==3) ? 1 : f4);
9191 }
9192 break;
9193
9194 case aVIRE:
9195 {
9196 if(dir==up)
9197 {
9198 tile+=2;
9199 }
9200
9201 tile+=fx;
9202 }
9203 break;
9204
9205 case aROPE:
9206 {
9207 tile+=(1-fx);
9208 flip = dir==left ? 1:0;
9209 }
9210 break;
9211
9212 case aZORA:
9213 {
9214 int32_t dl;
9215
9216
2/2
✓ Branch 0 taken 231 times.
✓ Branch 1 taken 822 times.
1053 if(clk<36)
9217 {
9218 231 dl=clk+5;
9219 231 goto waves2;
9220 }
9221
9222
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 402 times.
822 if(clk<36+66)
9223
2/2
✓ Branch 0 taken 198 times.
✓ Branch 1 taken 222 times.
420 tile=(dir==up)?o_tile+1:o_tile;
9224 else
9225 {
9226 402 dl=clk-36-66;
9227 waves2:
9228 633 tile=((dl/11)&1)+s_tile;
9229 633 basetile = s_tile;
9230 }
9231 }
9232 1053 break;
9233
9234 case aNEWZORA:
9235 {
9236 2952 f4=(clk/16)%4;
9237
9238 2952 tiledir(dir,true);
9239 int32_t dl;
9240
9241
4/4
✓ Branch 0 taken 2364 times.
✓ Branch 1 taken 588 times.
✓ Branch 2 taken 1290 times.
✓ Branch 3 taken 1074 times.
2952 if((clk>35)&&(clk<36+67)) //surfaced
9242 {
9243
4/4
✓ Branch 0 taken 921 times.
✓ Branch 1 taken 153 times.
✓ Branch 2 taken 135 times.
✓ Branch 3 taken 786 times.
1074 if((clk>=(35+10))&&(clk<(38+56))) //mouth open
9244 {
9245 786 tile+=80;
9246 786 } //mouth closed
9247 else
9248 {
9249 288 tile+=40;
9250 }
9251
9252 1074 tile+=f4;
9253 1074 }
9254 else
9255 {
9256
2/2
✓ Branch 0 taken 588 times.
✓ Branch 1 taken 1290 times.
1878 if(clk<36)
9257 {
9258 588 dl=clk+5;
9259 588 }
9260 else
9261 {
9262 1290 dl=clk-36-66;
9263 }
9264
9265 1878 tile+=((dl/5)&3);
9266 }
9267 }
9268 2952 break;
9269
9270 case a4FRM4EYE:
9271 case a2FRM4EYE:
9272 case a4FRM8EYE:
9273 case a4FRM8EYEB: //big version
9274 case a4FRM4EYEB:
9275 {
9276 tilerows = 2;
9277 int fakex = x + 8*(zc_max(1,txsz)-1);
9278 int fakey = y + 8*(zc_max(1,tysz)-1);
9279 double _MSVC2022_tmp1, _MSVC2022_tmp2;
9280 double ddir=atan2_MSVC2022_FIX(double(fakey-(Hero.y)),double(Hero.x-fakex));
9281 int32_t lookat=zc_oldrand()&15;
9282
9283 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
9284 {
9285 lookat=l_down;
9286 }
9287 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
9288 {
9289 lookat=down;
9290 }
9291 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
9292 {
9293 lookat=r_down;
9294 }
9295 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
9296 {
9297 lookat=right;
9298 }
9299 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
9300 {
9301 lookat=r_up;
9302 }
9303 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
9304 {
9305 lookat=up;
9306 }
9307 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
9308 {
9309 lookat=l_up;
9310 }
9311 else
9312 {
9313 lookat=left;
9314 }
9315
9316 int32_t dir2 = dir;
9317 dir = lookat;
9318 if (anim != a4FRM8EYEB && anim != a4FRM4EYEB) basetile = n_frame_n_dir(anim==a2FRM4EYE ? 2:4, anim==a4FRM8EYE ? 8 : 4, anim==a2FRM4EYE ? (f2&1):f4);
9319 else
9320 {
9321 tiledir_big(dir,(anim == a4FRM4EYEB));
9322 tile+=2*f4;
9323 ignore_extend = true;
9324 }
9325 dir = dir2;
9326 }
9327 break;
9328
9329 case aFLIP:
9330 {
9331 16892 flip = f2&1;
9332 }
9333 16892 break;
9334
9335 case a2FRM:
9336 {
9337 3515 tile += (1-f2);
9338 }
9339 3515 break;
9340
9341 case a2FRMB:
9342 {
9343 tile+= 2*(1-f2);
9344 ignore_extend = true;
9345 }
9346 break;
9347
9348 case a2FRM4DIR:
9349 {
9350 basetile = n_frame_n_dir(2, 4, f2&1);
9351 }
9352 break;
9353
9354 case a4FRM4DIRF:
9355 {
9356 38388 basetile = n_frame_n_dir(4,4,f4);
9357
9358
2/2
✓ Branch 0 taken 25704 times.
✓ Branch 1 taken 12684 times.
38388 if(clk2>0) //stopped to fire
9359 {
9360 12684 tile+=20;
9361
9362
2/2
✓ Branch 0 taken 7827 times.
✓ Branch 1 taken 4857 times.
12684 if(clk2<17) //firing
9363 {
9364 4857 tile+=20;
9365 4857 }
9366 12684 }
9367 }
9368 38388 break;
9369
9370 case a4FRM4DIR:
9371 {
9372 12051 basetile = n_frame_n_dir(4,4,f4);
9373 }
9374 12051 break;
9375
9376 case a4FRM8DIRF:
9377 {
9378 tilerows = 2;
9379 basetile = n_frame_n_dir(4,8,f4);
9380
9381 if(clk2>0) //stopped to fire
9382 {
9383 tile+=40;
9384
9385 if(clk2<17) //firing
9386 {
9387 tile+=40;
9388 }
9389 }
9390 }
9391 break;
9392
9393 case a4FRM8DIRB:
9394 case a4FRM8DIRFB:
9395 {
9396 tilerows = 2;
9397 tiledir_big(dir,false);
9398 tile+=2*f4;
9399 if(clk2>0 && anim == a4FRM8DIRFB) //stopped to fire
9400 {
9401 tile+=80;
9402
9403 if(clk2<17) //firing
9404 {
9405 tile+=80;
9406 }
9407 }
9408 ignore_extend = true;
9409 }
9410 break;
9411
9412 case a4FRM4DIRB:
9413 case a4FRM4DIRFB:
9414 {
9415 tilerows = 2;
9416 tiledir_big(dir,true);
9417 tile+=2*f4;
9418 if(clk2>0 && anim == a4FRM4DIRFB) //stopped to fire
9419 {
9420 tile+=40;
9421
9422 if(clk2<17) //firing
9423 {
9424 tile+=40;
9425 }
9426 }
9427 ignore_extend = true;
9428 }
9429 break;
9430
9431 case aOCTO:
9432 {
9433
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 2133 times.
✓ Branch 2 taken 1369 times.
✓ Branch 3 taken 2964 times.
✓ Branch 4 taken 3236 times.
9702 switch(dir)
9434 {
9435 case up:
9436 2133 flip = 2;
9437 2133 break;
9438
9439 case down:
9440 1369 flip = 0;
9441 1369 break;
9442
9443 case left:
9444 2964 flip = 0;
9445 2964 tile += 2;
9446 2964 break;
9447
9448 case right:
9449 3236 flip = 1;
9450 3236 tile += 2;
9451 3236 break;
9452 }
9453
9454 9702 tile+=f2;
9455 }
9456 9702 break;
9457
9458 case aWALK:
9459 {
9460
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1760 times.
✓ Branch 2 taken 2925 times.
✓ Branch 3 taken 2707 times.
✓ Branch 4 taken 1844 times.
9236 switch(dir)
9461 {
9462 case up:
9463 1760 tile+=3;
9464 1760 flip = f2;
9465 1760 break;
9466
9467 case down:
9468 2925 tile+=2;
9469 2925 flip = f2;
9470 2925 break;
9471
9472 case left:
9473 2707 flip=1;
9474 2707 tile += f2;
9475 2707 break;
9476
9477 case right:
9478 1844 flip=0;
9479 1844 tile += f2;
9480 1844 break;
9481 }
9482 }
9483 9236 break;
9484
9485 case aDWALK:
9486 {
9487
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 884 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
884 if((get_bit(quest_rules,qr_BRKNSHLDTILES)) && (dummy_bool[1]==true))
9488 {
9489 tile=s_tile;
9490 basetile = s_tile;
9491 }
9492
9493
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 196 times.
✓ Branch 2 taken 216 times.
✓ Branch 3 taken 256 times.
✓ Branch 4 taken 216 times.
884 switch(dir)
9494 {
9495 case up:
9496 196 tile+=2;
9497 196 flip=f2;
9498 196 break;
9499
9500 case down:
9501 216 flip=0;
9502 216 tile+=(1-f2);
9503 216 break;
9504
9505 case left:
9506 256 flip=1;
9507 256 tile+=(3+f2);
9508 256 break;
9509
9510 case right:
9511 216 flip=0;
9512 216 tile+=(3+f2);
9513 216 break;
9514 }
9515 }
9516 884 break;
9517
9518 case aTEK:
9519 {
9520
2/2
✓ Branch 0 taken 2282 times.
✓ Branch 1 taken 395 times.
2677 if(misc==0)
9521 {
9522 395 tile += f2;
9523 395 }
9524
2/2
✓ Branch 0 taken 1200 times.
✓ Branch 1 taken 1082 times.
2282 else if(misc!=1)
9525 {
9526 1082 ++tile;
9527 1082 }
9528 }
9529 2677 break;
9530
9531 case aNEWTEK:
9532 {
9533
2/2
✓ Branch 0 taken 1207 times.
✓ Branch 1 taken 8257 times.
9464 if(step<0) //up
9534 {
9535
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 922 times.
✓ Branch 2 taken 285 times.
1207 switch(clk3)
9536 {
9537 case left:
9538 922 flip=0;
9539 922 tile+=20;
9540 922 break;
9541
9542 case right:
9543 285 flip=0;
9544 285 tile+=24;
9545 285 break;
9546 }
9547 1207 }
9548
2/2
✓ Branch 0 taken 726 times.
✓ Branch 1 taken 7531 times.
8257 else if(step==0)
9549 {
9550
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 708 times.
✓ Branch 2 taken 18 times.
726 switch(clk3)
9551 {
9552 case left:
9553 708 flip=0;
9554 708 tile+=8;
9555 708 break;
9556
9557 case right:
9558 18 flip=0;
9559 18 tile+=12;
9560 18 break;
9561 }
9562 726 } //down
9563 else
9564 {
9565
3/3
✓ Branch 0 taken 202 times.
✓ Branch 1 taken 5292 times.
✓ Branch 2 taken 2037 times.
7531 switch(clk3)
9566 {
9567 case left:
9568 5292 flip=0;
9569 5292 tile+=28;
9570 5292 break;
9571
9572 case right:
9573 2037 flip=0;
9574 2037 tile+=32;
9575 2037 break;
9576 }
9577 }
9578
9579
2/2
✓ Branch 0 taken 3977 times.
✓ Branch 1 taken 5487 times.
9464 if(misc==0)
9580 {
9581 5487 tile+=f4;
9582 5487 }
9583
2/2
✓ Branch 0 taken 1645 times.
✓ Branch 1 taken 2332 times.
3977 else if(misc!=1)
9584 {
9585 2332 tile+=2;
9586 2332 }
9587 }
9588 9464 break;
9589
9590 case aARMOS:
9591 {
9592 if(!fading)
9593 {
9594 tile += fx;
9595
9596 if(dir==up)
9597 tile += 2;
9598 }
9599 }
9600 break;
9601
9602 case aARMOS4:
9603 {
9604 switch(dir)
9605 {
9606 case up:
9607 flip=0;
9608 break;
9609
9610 case down:
9611 flip=0;
9612 tile+=4;
9613 break;
9614
9615 case left:
9616 flip=0;
9617 tile+=8;
9618 break;
9619
9620 case right:
9621 flip=0;
9622 tile+=12;
9623 break;
9624 }
9625
9626 if(!fading)
9627 {
9628 tile+=f4;
9629 }
9630 }
9631 break;
9632
9633 case aGHINI:
9634 {
9635 switch(dir)
9636 {
9637 case 8:
9638 case 9:
9639 case up:
9640 ++tile;
9641 flip=0;
9642 break;
9643
9644 case 15:
9645 ++tile;
9646 flip=1;
9647 break;
9648
9649 case 10:
9650 case 11:
9651 case right:
9652 flip=1;
9653 break;
9654
9655 default:
9656 flip=0;
9657 break;
9658 }
9659 }
9660 break;
9661
9662 case a2FRMPOS:
9663 {
9664 16798 tile+=posframe;
9665 }
9666 16798 break;
9667
9668 case a4FRMPOS4DIR:
9669 {
9670 basetile = n_frame_n_dir(4,4,0);
9671 // tile+=f2;
9672 tile+=posframe;
9673 }
9674 break;
9675
9676 case a4FRMPOS4DIRF:
9677 {
9678 basetile = n_frame_n_dir(4,4,0);
9679
9680 if(clk2>0) //stopped to fire
9681 {
9682 tile+=20;
9683
9684 if(clk2<17) //firing
9685 {
9686 tile+=20;
9687 }
9688 }
9689
9690 // tile+=f2;
9691 tile+=posframe;
9692 }
9693 break;
9694
9695 case a4FRMPOS8DIR:
9696 {
9697 39193 tilerows = 2;
9698 39193 int32_t n = tile;
9699 39193 basetile = n_frame_n_dir(4,8,0);
9700 // tile+=f2;
9701 39193 tile+=posframe;
9702 }
9703 39193 break;
9704
9705 case a4FRMPOS8DIRF:
9706 {
9707 tilerows = 2;
9708 basetile = n_frame_n_dir(4,8,0);
9709
9710 if(clk2>0) //stopped to fire
9711 {
9712 tile+=40;
9713
9714 if(clk2<17) //firing
9715 {
9716 tile+=40;
9717 }
9718 }
9719
9720 tile+=posframe;
9721 }
9722 break;
9723
9724 case aNEWLEV:
9725 {
9726 tiledir(dir,true);
9727
9728 switch(misc)
9729 {
9730 case -1:
9731 case 0:
9732 return;
9733
9734 case 1:
9735
9736 // case 5: cs = d->misc2; break;
9737 case 5:
9738 cs = dmisc2;
9739 break;
9740
9741 case 2:
9742 case 4:
9743 tile += 20;
9744 break;
9745
9746 case 3:
9747 tile += 40;
9748 break;
9749 }
9750
9751 tile+=f4;
9752 }
9753 break;
9754
9755 case aLEV:
9756 {
9757 721 f4 = ((clk/5)&1);
9758
9759
4/5
✓ Branch 0 taken 427 times.
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 219 times.
721 switch(misc)
9760 {
9761 case -1:
9762 case 0:
9763 427 return;
9764
9765 case 1:
9766
9767 // case 5: tile += (f2) ? 1 : 0; cs = d->misc2; break;
9768 case 5:
9769 51 tile += (f2) ? 1 : 0;
9770 51 cs = dmisc2;
9771 51 break;
9772
9773 case 2:
9774 case 4:
9775 24 tile += 2;
9776 24 break;
9777
9778 case 3:
9779 219 tile += (f4) ? 4 : 3;
9780 219 break;
9781 }
9782 }
9783 294 break;
9784
9785 case aWALLM:
9786 {
9787
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4548 times.
4548 if(!dummy_bool[1])
9788 {
9789 4548 tile += f2;
9790 4548 }
9791 }
9792 4548 break;
9793
9794 case aNEWWALLM:
9795 {
9796 3737 int32_t tempdir=0;
9797
9798
3/4
✓ Branch 0 taken 1553 times.
✓ Branch 1 taken 740 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1444 times.
3737 switch(misc)
9799 {
9800 case 1:
9801 case 2:
9802 740 tempdir=clk3;
9803 740 break;
9804
9805 case 3:
9806 case 4:
9807 case 5:
9808 1553 tempdir=dir;
9809 1553 break;
9810
9811 case 6:
9812 case 7:
9813 tempdir=clk3^1;
9814 break;
9815 }
9816
9817 3737 tiledir(tempdir,true);
9818
9819
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3737 times.
3737 if(!dummy_bool[1])
9820 {
9821 3737 tile+=f4;
9822 3737 }
9823 }
9824 3737 break;
9825
9826 case a4FRMNODIR:
9827 {
9828 tile+=f4;
9829 }
9830 break;
9831
9832 } // switch(d->anim)
9833
9834 // flashing
9835 // if(d->flags2 & guy_flashing)
9836
2/2
✓ Branch 0 taken 173943 times.
✓ Branch 1 taken 2696 times.
176639 if(flags2 & guy_flashing)
9837 {
9838 2696 cs = (frame&3) + 6;
9839 2696 }
9840
9841
1/2
✓ Branch 0 taken 176639 times.
✗ Branch 1 not taken.
176639 if(flags2&guy_transparent)
9842 {
9843 drawstyle=1;
9844 }
9845
9846 176639 int32_t change = tile-basetile;
9847
9848
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 176639 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
176639 if(extend > 2 && (!ignore_extend || get_bit(quest_rules, qr_BROKEN_BIG_ENEMY_ANIMATION)))
9849 {
9850 if(basetile/TILES_PER_ROW==(basetile+((txsz*change)/tilerows))/TILES_PER_ROW)
9851 {
9852 tile=basetile+txsz*change;
9853 }
9854 else
9855 {
9856 tile=basetile+(txsz*change)+((tysz-1)*TILES_PER_ROW)*(((basetile+txsz*change)/TILES_PER_ROW)-(basetile/TILES_PER_ROW));
9857 }
9858 }
9859 else
9860 {
9861 176639 tile=basetile+change;
9862 }
9863 177066 }
9864
9865 220 int32_t wpnsfx(int32_t wpn)
9866 {
9867
3/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
✓ Branch 3 taken 56 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 130 times.
220 switch(wpn)
9868 {
9869 case ewFireTrail:
9870 case ewFlame:
9871 case ewFlame2Trail:
9872 case ewFlame2:
9873 return WAV_FIRE;
9874
9875 case ewWind:
9876 case ewMagic:
9877 return WAV_WAND;
9878
9879 case ewIce:
9880 return WAV_ZN1ICE;
9881
9882 case ewRock:
9883
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 if(get_bit(quest_rules,qr_MORESOUNDS)) return WAV_ZN1ROCK;
9884 130 break;
9885
9886 case ewFireball2:
9887 case ewFireball:
9888
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if(get_bit(quest_rules,qr_MORESOUNDS)) return WAV_ZN1FIREBALL;
9889 34 }
9890
9891 220 return -1;
9892 220 }
9893
9894 282245 int32_t enemy::run_script(int32_t mode)
9895 {
9896
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 282245 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
282245 if(switch_hooked && !get_bit(quest_rules, qr_SWITCHOBJ_RUN_SCRIPT)) return RUNSCRIPT_OK;
9897
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 282245 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
282245 if (script <= 0 || !doscript || FFCore.getQuestHeaderInfo(vZelda) < 0x255 || FFCore.system_suspend[susptNPCSCRIPTS])
9898 282245 return RUNSCRIPT_OK;
9899 int32_t ret = RUNSCRIPT_OK;
9900 alloc_scriptmem();
9901 switch(mode)
9902 {
9903 case MODE_NORMAL:
9904 return ZScriptVersion::RunScript(SCRIPT_NPC, script, getUID());
9905 case MODE_WAITDRAW:
9906 if(waitdraw)
9907 {
9908 ret = ZScriptVersion::RunScript(SCRIPT_NPC, script, getUID());
9909 waitdraw = 0;
9910 }
9911 break;
9912 }
9913 return ret;
9914 282245 }
9915
9916 /********************************/
9917 /********* Guy Class **********/
9918 /********************************/
9919
9920 // good guys, fires, fairy, and other non-enemies
9921 // based on enemy class b/c guys in dungeons act sort of like enemies
9922 // also easier to manage all the guys this way
9923 87 guy::guy(zfix X,zfix Y,int32_t Id,int32_t Clk,bool mg) : enemy(X,Y,Id,Clk)
9924 87 {
9925 29 mainguy=mg;
9926 29 canfreeze=false;
9927 29 dir=down;
9928
3/6
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 29 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
29 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
9929 29 hxofs=2;
9930 29 hzsz=8;
9931 29 hxsz=12;
9932 29 hysz=17;
9933
9934
8/12
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 22 times.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 3 times.
29 if(!superman && (!isdungeon() || id==gFAIRY || id==gFIRE || id==gZELDA))
9935 {
9936 26 superman = 1;
9937 26 hxofs=1000;
9938 26 }
9939 58 }
9940
9941 12436 bool guy::animate(int32_t index)
9942 {
9943
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12436 times.
12436 if(switch_hooked) return enemy::animate(index);
9944
6/6
✓ Branch 0 taken 4830 times.
✓ Branch 1 taken 7606 times.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 4805 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 13 times.
12436 if(mainguy && clk==0 && misc==0)
9945 {
9946 13 setupscreen();
9947 13 misc = 1;
9948 13 }
9949
9950
4/4
✓ Branch 0 taken 4830 times.
✓ Branch 1 taken 7606 times.
✓ Branch 2 taken 4822 times.
✓ Branch 3 taken 8 times.
12436 if(mainguy && fadeclk==0)
9951 8 return true;
9952
9953 12428 hp=256; // good guys never die...
9954
9955
4/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 12395 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 1 times.
12428 if(hclk && !clk2)
9956 {
9957 // but if they get hit...
9958 1 ++clk2; // only do this once
9959
9960
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(!get_bit(quest_rules,qr_NOGUYFIRES))
9961 {
9962 1 addenemy(BSZ?64:72,68,eSHOOTFBALL,0);
9963 1 addenemy(BSZ?176:168,68,eSHOOTFBALL,0);
9964 1 }
9965 1 }
9966
9967 12428 return enemy::animate(index);
9968 12436 }
9969
9970 12475 void guy::draw(BITMAP *dest)
9971 {
9972 12475 update_enemy_frame();
9973
9974
6/6
✓ Branch 0 taken 4843 times.
✓ Branch 1 taken 7632 times.
✓ Branch 2 taken 528 times.
✓ Branch 3 taken 4315 times.
✓ Branch 4 taken 264 times.
✓ Branch 5 taken 264 times.
12475 if(!mainguy || fadeclk<0 || fadeclk&1)
9975 12211 enemy::draw(dest);
9976 12475 }
9977
9978 /*******************************/
9979 /********* Enemies *********/
9980 /*******************************/
9981
9982 eFire::eFire(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
9983 {
9984 clk4=0;
9985 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
9986 // Spawn type
9987 if(flags & guy_fadeflicker)
9988 {
9989 clk=0;
9990 superman = 1;
9991 fading=fade_flicker;
9992 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
9993 dir=down;
9994
9995 if(!canmove(down,(zfix)8,spw_none,false))
9996 clk3=int32_t(13.0/step);
9997 }
9998 else if(flags & guy_fadeinstant)
9999 {
10000 clk=0;
10001 }
10002 SIZEflags = d->SIZEflags;
10003 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10004 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10005 // al_trace("Enemy txsz:%i\n", txsz);
10006 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10007 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10008 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10009 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10010 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10011 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10012 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10013 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10014 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10015 {
10016 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10017 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10018 }
10019
10020 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) d->zofs = (int32_t)zofs;
10021 }
10022
10023 bool eFire::animate(int32_t index)
10024 {
10025 if(switch_hooked) return enemy::animate(index);
10026 if(fallclk||drownclk) return enemy::animate(index);
10027 if(fading)
10028 {
10029 if(++clk4 > 60)
10030 {
10031 clk4=0;
10032 superman=0;
10033 fading=0;
10034
10035 if(flags2&cmbflag_armos && z==0 && fakez==0)
10036 removearmos(x,y,ffcactivated);
10037
10038 clk2=0;
10039
10040 if(!canmove(down,(zfix)8,spw_none,false))
10041 {
10042 dir=0;
10043 y = y.getInt() & 0xF0;
10044 }
10045
10046 return Dead(index);
10047 }
10048 else if(flags2&cmbflag_armos && z==0 && fakez==0 && clk==0)
10049 removearmos(x,y,ffcactivated);
10050 }
10051
10052 return enemy::animate(index);
10053 }
10054
10055 void eFire::draw(BITMAP *dest)
10056 {
10057 update_enemy_frame();
10058 enemy::draw(dest);
10059 }
10060
10061 int32_t eFire::takehit(weapon *w)
10062 {
10063 int32_t wpnId = w->id;
10064 int32_t wpnDir = w->dir;
10065
10066 if(wpnId==wHammer && shield && (flags & guy_bkshield)
10067 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
10068 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
10069 {
10070 shield = false;
10071 flags &= ~(inv_left|inv_right|inv_back|inv_front);
10072
10073 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10074 o_tile=s_tile;
10075 }
10076
10077 int32_t ret = enemy::takehit(w);
10078 return ret;
10079 }
10080
10081 void eFire::break_shield()
10082 {
10083 if(!shield)
10084 return;
10085
10086 flags&=~(inv_front | inv_back | inv_left | inv_right);
10087 shield=false;
10088
10089 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10090 o_tile=s_tile;
10091 }
10092
10093 eOther::eOther(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10094 {
10095 //zprint2("npct other::other\n");
10096 clk4=0;
10097 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
10098
10099 // Spawn type
10100 if(flags & guy_fadeflicker)
10101 {
10102 clk=0;
10103 superman = 1;
10104 fading=fade_flicker;
10105 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
10106 dir=down;
10107
10108 if(!canmove(down,(zfix)8,spw_none,false))
10109 clk3=int32_t(13.0/step);
10110 }
10111 else if(flags & guy_fadeinstant)
10112 {
10113 clk=0;
10114 }
10115 SIZEflags = d->SIZEflags;
10116 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10117 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10118 // al_trace("Enemy txsz:%i\n", txsz);
10119 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10120 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10121 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10122 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10123 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10124 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10125 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10126 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10127 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10128 {
10129 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10130 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10131 }
10132
10133 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10134 }
10135
10136 bool eOther::animate(int32_t index)
10137 {
10138 if(switch_hooked) return enemy::animate(index);
10139 if(fallclk||drownclk) return enemy::animate(index);
10140 //zprint2("npct other::animate\n");
10141 if(fading)
10142 {
10143 if(++clk4 > 60)
10144 {
10145 clk4=0;
10146 superman=0;
10147 fading=0;
10148
10149 if(flags2&cmbflag_armos && z==0 && fakez==0)
10150 removearmos(x,y,ffcactivated);
10151
10152 clk2=0;
10153
10154 if(!canmove(down,(zfix)8,spw_none,false))
10155 {
10156 dir=0;
10157 y = y.getInt() & 0xF0;
10158 }
10159
10160 return Dead(index);
10161 }
10162 else if(flags2&cmbflag_armos && z==0 && fakez==0 && clk==0)
10163 removearmos(x,y,ffcactivated);
10164 }
10165
10166 return enemy::animate(index);
10167 }
10168
10169 void eOther::draw(BITMAP *dest)
10170 {
10171 update_enemy_frame();
10172 enemy::draw(dest);
10173 }
10174
10175 int32_t eOther::takehit(weapon *w)
10176 {
10177 int32_t wpnId = w->id;
10178 int32_t wpnDir = w->dir;
10179
10180 if(wpnId==wHammer && shield && (flags & guy_bkshield)
10181 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
10182 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
10183 {
10184 shield = false;
10185 flags &= ~(inv_left|inv_right|inv_back|inv_front);
10186
10187 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10188 o_tile=s_tile;
10189 }
10190
10191 int32_t ret = enemy::takehit(w);
10192 return ret;
10193 }
10194
10195 void eOther::break_shield()
10196 {
10197 if(!shield)
10198 return;
10199
10200 flags&=~(inv_front | inv_back | inv_left | inv_right);
10201 shield=false;
10202
10203 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10204 o_tile=s_tile;
10205 }
10206
10207
10208 eScript::eScript(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10209 {
10210 clk4=0;
10211 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
10212
10213 // Spawn type
10214 if(flags & guy_fadeflicker)
10215 {
10216 clk=0;
10217 superman = 1;
10218 fading=fade_flicker;
10219 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
10220 dir=down;
10221
10222 if(!canmove(down,(zfix)8,spw_none,false))
10223 clk3=int32_t(13.0/step);
10224 }
10225 else if(flags & guy_fadeinstant)
10226 {
10227 clk=0;
10228 }
10229 SIZEflags = d->SIZEflags;
10230 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10231 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10232 // al_trace("Enemy txsz:%i\n", txsz);
10233 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10234 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10235 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10236 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10237 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10238 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10239 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10240 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10241 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10242 {
10243 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10244 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10245 }
10246
10247 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10248 }
10249
10250 bool eScript::animate(int32_t index)
10251 {
10252 if(switch_hooked) return enemy::animate(index);
10253 if(fallclk||drownclk) return enemy::animate(index);
10254 if(fading)
10255 {
10256 if(++clk4 > 60)
10257 {
10258 clk4=0;
10259 superman=0;
10260 fading=0;
10261
10262 if(flags2&cmbflag_armos && z==0 && fakez==0)
10263 removearmos(x,y,ffcactivated);
10264
10265 clk2=0;
10266
10267 if(!canmove(down,(zfix)8,spw_none,false))
10268 {
10269 dir=0;
10270 y = y.getInt() & 0xF0;
10271 }
10272
10273 return Dead(index);
10274 }
10275 else if(flags2&cmbflag_armos && z==0 && fakez==0 && clk==0)
10276 removearmos(x,y,ffcactivated);
10277 }
10278
10279 return enemy::animate(index);
10280 }
10281
10282 void eScript::draw(BITMAP *dest)
10283 {
10284 update_enemy_frame();
10285 enemy::draw(dest);
10286 }
10287
10288 int32_t eScript::takehit(weapon *w)
10289 {
10290 int32_t wpnId = w->id;
10291 int32_t wpnDir = w->dir;
10292
10293 if(wpnId==wHammer && shield && (flags & guy_bkshield)
10294 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
10295 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
10296 {
10297 shield = false;
10298 flags &= ~(inv_left|inv_right|inv_back|inv_front);
10299
10300 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10301 o_tile=s_tile;
10302 }
10303
10304 int32_t ret = enemy::takehit(w);
10305 return ret;
10306 }
10307
10308 void eScript::break_shield()
10309 {
10310 if(!shield)
10311 return;
10312
10313 flags&=~(inv_front | inv_back | inv_left | inv_right);
10314 shield=false;
10315
10316 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10317 o_tile=s_tile;
10318 }
10319
10320
10321 eFriendly::eFriendly(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10322 {
10323 clk4=0;
10324 hyofs = -32768; //No hitbox initially.
10325 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
10326
10327 // Spawn type
10328 if(flags & guy_fadeflicker)
10329 {
10330 clk=0;
10331 superman = 1;
10332 fading=fade_flicker;
10333 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
10334 dir=down;
10335
10336 if(!canmove(down,(zfix)8,spw_none,false))
10337 clk3=int32_t(13.0/step);
10338 }
10339 else if(flags & guy_fadeinstant)
10340 {
10341 clk=0;
10342 }
10343 SIZEflags = d->SIZEflags;
10344 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10345 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10346 // al_trace("Enemy txsz:%i\n", txsz);
10347 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10348 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10349 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10350 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10351 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10352 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10353 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10354 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10355 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10356 {
10357 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10358 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10359 }
10360
10361 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10362 }
10363
10364 bool eFriendly::animate(int32_t index)
10365 {
10366 if(switch_hooked) return enemy::animate(index);
10367 if(fallclk||drownclk) return enemy::animate(index);
10368 if(fading)
10369 {
10370 if(++clk4 > 60)
10371 {
10372 clk4=0;
10373 superman=0;
10374 fading=0;
10375
10376 if(flags2&cmbflag_armos && z==0 && fakez==0)
10377 removearmos(x,y,ffcactivated);
10378
10379 clk2=0;
10380
10381 if(!canmove(down,(zfix)8,spw_none,false))
10382 {
10383 dir=0;
10384 y = y.getInt() & 0xF0;
10385 }
10386
10387 return Dead(index);
10388 }
10389 else if(flags2&cmbflag_armos && z==0 && fakez==0 && clk==0)
10390 removearmos(x,y,ffcactivated);
10391 }
10392
10393 return enemy::animate(index);
10394 }
10395
10396 void eFriendly::draw(BITMAP *dest)
10397 {
10398 update_enemy_frame();
10399 enemy::draw(dest);
10400 }
10401
10402 int32_t eFriendly::takehit(weapon *w)
10403 {
10404 int32_t wpnId = w->id;
10405 int32_t wpnDir = w->dir;
10406
10407 if(wpnId==wHammer && shield && (flags & guy_bkshield)
10408 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
10409 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
10410 {
10411 shield = false;
10412 flags &= ~(inv_left|inv_right|inv_back|inv_front);
10413
10414 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10415 o_tile=s_tile;
10416 }
10417
10418 int32_t ret = enemy::takehit(w);
10419 return ret;
10420 }
10421
10422 void eFriendly::break_shield()
10423 {
10424 if(!shield)
10425 return;
10426
10427 flags&=~(inv_front | inv_back | inv_left | inv_right);
10428 shield=false;
10429
10430 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10431 o_tile=s_tile;
10432 }
10433
10434
10435 786 void enemy::removearmos(int32_t ax,int32_t ay, word ffcactive)
10436 {
10437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 786 times.
786 if (ffcactive)
10438 {
10439 removearmosffc(ffcactive-1);
10440 return;
10441 }
10442
1/2
✓ Branch 0 taken 786 times.
✗ Branch 1 not taken.
786 if(did_armos)
10443 {
10444 786 return;
10445 }
10446
10447 did_armos=true;
10448 ax&=0xF0;
10449 ay&=0xF0;
10450 int32_t cd = (ax>>4)+ay;
10451 int32_t f = MAPFLAG(ax,ay);
10452 int32_t f2 = MAPCOMBOFLAG(ax,ay);
10453
10454 if(combobuf[tmpscr->data[cd]].type!=cARMOS)
10455 {
10456 return;
10457 }
10458
10459 tmpscr->data[cd] = tmpscr->undercombo;
10460 tmpscr->cset[cd] = tmpscr->undercset;
10461 tmpscr->sflag[cd] = 0;
10462
10463 if(f == mfARMOS_SECRET || f2 == mfARMOS_SECRET)
10464 {
10465 tmpscr->data[cd] = tmpscr->secretcombo[sSTAIRS];
10466 tmpscr->cset[cd] = tmpscr->secretcset[sSTAIRS];
10467 tmpscr->sflag[cd]=tmpscr->secretflag[sSTAIRS];
10468 sfx(tmpscr->secretsfx);
10469 }
10470
10471 if(f == mfARMOS_ITEM || f2 == mfARMOS_ITEM)
10472 {
10473 if(!getmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM) || (tmpscr->flags9&fBELOWRETURN))
10474 {
10475 additem(ax,ay,tmpscr->catchall, (ipONETIME2 + ipBIGRANGE) | ((tmpscr->flags3&fHOLDITEM) ? ipHOLDUP : 0) | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0));
10476 sfx(tmpscr->secretsfx);
10477 }
10478 }
10479
10480 putcombo(scrollbuf,ax,ay,tmpscr->data[cd],tmpscr->cset[cd]);
10481 786 }
10482
10483 void enemy::removearmosffc(int32_t pos)
10484 {
10485 if(did_armos)
10486 {
10487 return;
10488 }
10489
10490 did_armos=true;
10491 ffcdata& ffc = tmpscr->ffcs[pos];
10492 newcombo const& cmb = combobuf[ffc.getData()];
10493 int32_t f2 = cmb.flag;
10494
10495 if(cmb.type!=cARMOS)
10496 {
10497 return;
10498 }
10499
10500 ffc.setData(tmpscr->undercombo);
10501 ffc.cset = tmpscr->undercset;
10502
10503 if(f2 == mfARMOS_SECRET)
10504 {
10505 ffc.setData(tmpscr->secretcombo[sSTAIRS]);
10506 ffc.cset = tmpscr->secretcset[sSTAIRS];
10507 sfx(tmpscr->secretsfx);
10508 }
10509
10510 if(f2 == mfARMOS_ITEM)
10511 {
10512 if(!getmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM) || (tmpscr->flags9&fBELOWRETURN))
10513 {
10514 additem(ffc.x,ffc.y,tmpscr->catchall, (ipONETIME2 + ipBIGRANGE) | ((tmpscr->flags3&fHOLDITEM) ? ipHOLDUP : 0) | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0));
10515 sfx(tmpscr->secretsfx);
10516 }
10517 }
10518
10519 putcombo(scrollbuf,ffc.x,ffc.y,ffc.getData(),ffc.cset);
10520 }
10521
10522
10523 eGhini::eGhini(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10524 {
10525 fading=fade_flicker;
10526 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
10527 dir=12;
10528 movestatus=1;
10529 step=0;
10530 clk=0;
10531 clk4=0;
10532 SIZEflags = d->SIZEflags;
10533 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10534 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10535 // al_trace("Enemy txsz:%i\n", txsz);
10536 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10537 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10538 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10539 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10540 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10541 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10542 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10543 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10544 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10545 {
10546 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10547 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10548 }
10549
10550 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10551 }
10552
10553 bool eGhini::animate(int32_t index)
10554 {
10555 if(switch_hooked) return enemy::animate(index);
10556 if(fallclk||drownclk) return enemy::animate(index);
10557 if(dying)
10558 return Dead(index);
10559
10560 if(dmisc1)
10561 {
10562 if(misc)
10563 {
10564 if(clk4>160)
10565 misc=2;
10566
10567 floater_walk((misc==1)?0:rate,hrate,zslongToFix(dstep*100),zslongToFix(dstep*10),10,dmisc16,dmisc17); //120,10);
10568 removearmos(x,y,ffcactivated);
10569 }
10570 else if(clk4>=60)
10571 {
10572 misc=1;
10573 clk3=32;
10574 fading=0;
10575 if (ffcactivated > 0)
10576 {
10577 guygridffc[ffcactivated-1] = 0;
10578 removearmosffc(ffcactivated-1);
10579 }
10580 else
10581 {
10582 guygrid[(int32_t(y)&0xF0)+(int32_t(x)>>4)]=0;
10583 removearmos(x,y);
10584 }
10585 }
10586 }
10587
10588 clk4++;
10589
10590 return enemy::animate(index);
10591 }
10592
10593 void eGhini::draw(BITMAP *dest)
10594 {
10595 update_enemy_frame();
10596 enemy::draw(dest);
10597 }
10598
10599 void eGhini::kickbucket()
10600 {
10601 hp=-1000; // don't call death_sfx()
10602 }
10603
10604
3/6
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
76 eTektite::eTektite(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10605 57 {
10606
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 old_y=y;
10607 19 dir=down;
10608 19 misc=1;
10609 19 clk=-15;
10610
10611
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if(!BSZ)
10612
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 clk*=zc_oldrand()%3+1;
10613
10614 // avoid divide by 0 errors
10615
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if(dmisc1 == 0)
10616 dmisc1 = 24;
10617
10618
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if(dmisc2 == 0)
10619 dmisc2 = 3;
10620
10621 //nets+760;
10622 19 SIZEflags = d->SIZEflags;
10623
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10624 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10625 // al_trace("Enemy txsz:%i\n", txsz);
10626
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10627
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10628
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10629
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10630
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10631
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10632 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10633
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10634
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10635 {
10636 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10637 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10638 }
10639
10640
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10641 38 }
10642
10643 5994 bool eTektite::animate(int32_t index)
10644 {
10645
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5994 times.
5994 if(switch_hooked) return enemy::animate(index);
10646
4/4
✓ Branch 0 taken 5984 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 5974 times.
5994 if(fallclk||drownclk) return enemy::animate(index);
10647
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 5848 times.
5974 if(dying)
10648 126 return Dead(index);
10649
10650
2/2
✓ Branch 0 taken 5708 times.
✓ Branch 1 taken 140 times.
5848 if(clk==0)
10651 {
10652 140 removearmos(x,y,ffcactivated);
10653 140 }
10654
10655
2/2
✓ Branch 0 taken 2612 times.
✓ Branch 1 taken 3236 times.
5848 if(get_bit(quest_rules,qr_ENEMIESZAXIS))
10656 {
10657 3236 y=floor_y;
10658 3236 }
10659
10660
8/10
✓ Branch 0 taken 5243 times.
✓ Branch 1 taken 605 times.
✓ Branch 2 taken 4959 times.
✓ Branch 3 taken 284 times.
✓ Branch 4 taken 4959 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4959 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 10 times.
5848 if(clk>=0 && !stunclk && !frozenclock && (!watch || misc==0))
10661 {
10662
4/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2111 times.
✓ Branch 2 taken 1249 times.
✓ Branch 3 taken 1599 times.
4969 switch(misc)
10663 {
10664 case 0: // normal
10665
2/2
✓ Branch 0 taken 2071 times.
✓ Branch 1 taken 40 times.
2111 if(!(zc_oldrand()%dmisc1))
10666 {
10667 40 misc=1;
10668 40 clk2=32;
10669 40 }
10670
10671 2111 break;
10672
10673 case 1: // waiting to pounce
10674
2/2
✓ Branch 0 taken 1182 times.
✓ Branch 1 taken 67 times.
1249 if(--clk2<=0)
10675 {
10676 67 int32_t r=zc_oldrand();
10677 67 misc=2;
10678 67 step=0-(zslongToFix(dstep*100)); // initial speed
10679 67 clk3=(r&1)+2; // left or right
10680 67 clk2start=clk2=(r&31)+10; // flight time
10681
10682
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 5 times.
67 if(y<32) clk2+=2; // make them come down from top of screen
10683
10684
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 16 times.
67 if(y>112) clk2-=2; // make them go back up
10685
10686 67 cstart=c = 9-((r&31)>>3); // time before gravity kicks in
10687 67 }
10688
10689 1249 break;
10690
10691 case 2: // in flight
10692 1599 move(step);
10693
10694
2/2
✓ Branch 0 taken 743 times.
✓ Branch 1 taken 856 times.
1599 if(step>0) //going down
10695 {
10696
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 743 times.
743 if(COMBOTYPE(x+8,y+16)==cNOJUMPZONE)
10697 {
10698 step=0-step;
10699 }
10700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 743 times.
743 else if(COMBOTYPE(x+8,y+16)==cNOENEMY)
10701 {
10702 step=0-step;
10703 }
10704
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 743 times.
743 else if(ispitfall(x+8,y+16))
10705 {
10706 step=0-step;
10707 }
10708
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 743 times.
743 else if(MAPFLAG(x+8,y+16)==mfNOENEMY)
10709 {
10710 step=0-step;
10711 }
10712
1/2
✓ Branch 0 taken 743 times.
✗ Branch 1 not taken.
743 else if(MAPCOMBOFLAG(x+8,y+16)==mfNOENEMY)
10713 {
10714 step=0-step;
10715 }
10716 743 }
10717
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 801 times.
856 else if(step<0)
10718 {
10719
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 801 times.
801 if(COMBOTYPE(x+8,y)==cNOJUMPZONE)
10720 {
10721 step=0-step;
10722 }
10723
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 801 times.
801 else if(COMBOTYPE(x+8,y)==cNOENEMY)
10724 {
10725 step=0-step;
10726 }
10727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 801 times.
801 else if(ispitfall(x+8,y))
10728 {
10729 step=0-step;
10730 }
10731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 801 times.
801 else if(MAPFLAG(x+8,y)==mfNOENEMY)
10732 {
10733 step=0-step;
10734 }
10735
1/2
✓ Branch 0 taken 801 times.
✗ Branch 1 not taken.
801 else if(MAPCOMBOFLAG(x+8,y)==mfNOENEMY)
10736 {
10737 step=0-step;
10738 }
10739 801 }
10740
10741
2/2
✓ Branch 0 taken 912 times.
✓ Branch 1 taken 687 times.
1599 if(clk3==left)
10742 {
10743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 912 times.
912 if(COMBOTYPE(x,y+8)==cNOJUMPZONE)
10744 {
10745 clk3^=1;
10746 }
10747
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 912 times.
912 else if(COMBOTYPE(x,y+8)==cNOENEMY)
10748 {
10749 clk3^=1;
10750 }
10751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 912 times.
912 else if(ispitfall(x,y+8))
10752 {
10753 clk3^=1;
10754 }
10755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 912 times.
912 else if(MAPFLAG(x,y+8)==mfNOENEMY)
10756 {
10757 clk3^=1;
10758 }
10759
1/2
✓ Branch 0 taken 912 times.
✗ Branch 1 not taken.
912 else if(MAPCOMBOFLAG(x,y+8)==mfNOENEMY)
10760 {
10761 clk3^=1;
10762 }
10763 912 }
10764 else
10765 {
10766
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 687 times.
687 if(COMBOTYPE(x+16,y+8)==cNOJUMPZONE)
10767 {
10768 clk3^=1;
10769 }
10770
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 687 times.
687 else if(COMBOTYPE(x+16,y+8)==cNOENEMY)
10771 {
10772 clk3^=1;
10773 }
10774
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 687 times.
687 else if(ispitfall(x+16,y+8))
10775 {
10776 clk3^=1;
10777 }
10778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 687 times.
687 else if(MAPFLAG(x+16,y+8)==mfNOENEMY)
10779 {
10780 clk3^=1;
10781 }
10782
1/2
✓ Branch 0 taken 687 times.
✗ Branch 1 not taken.
687 else if(MAPCOMBOFLAG(x+16,y+8)==mfNOENEMY)
10783 {
10784 clk3^=1;
10785 }
10786 }
10787
10788 1599 --c;
10789
10790
4/4
✓ Branch 0 taken 494 times.
✓ Branch 1 taken 1105 times.
✓ Branch 2 taken 1032 times.
✓ Branch 3 taken 567 times.
1599 if(c<0 && step<zslongToFix(dstep*100))
10791 {
10792 567 step+=zslongToFix(dmisc3*100);
10793 567 }
10794
10795 1599 int32_t nb=get_bit(quest_rules,qr_NOBORDER) ? 16 : 0;
10796
10797
2/2
✓ Branch 0 taken 1597 times.
✓ Branch 1 taken 2 times.
1599 if(x<=16-nb) clk3=right;
10798
10799
2/2
✓ Branch 0 taken 1597 times.
✓ Branch 1 taken 2 times.
1599 if(x>=224+nb) clk3=left;
10800
10801 1599 x += (clk3==left) ? -1 : 1;
10802
10803
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 1534 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1529 times.
1599 if((--clk2<=0 && y>=16-nb) || y>=144+nb)
10804 {
10805
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
70 if(y>=144+nb && get_bit(quest_rules,qr_ENEMIESZAXIS))
10806 {
10807 step=0-step;
10808 y--;
10809 }
10810
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 12 times.
60 else if(zc_oldrand()%dmisc2) //land and wait
10811 {
10812 48 clk=misc=0;
10813 48 } //land and jump again
10814 else
10815 {
10816 12 misc=1;
10817 12 clk2=0;
10818 }
10819 60 }
10820
10821 1589 break;
10822 } // switch
10823 4959 }
10824
10825
4/4
✓ Branch 0 taken 3236 times.
✓ Branch 1 taken 2622 times.
✓ Branch 2 taken 2474 times.
✓ Branch 3 taken 762 times.
5858 if(get_bit(quest_rules,qr_ENEMIESZAXIS) && misc==2)
10826 {
10827
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 762 times.
762 if (moveflags & FLAG_USE_FAKE_Z)
10828 {
10829 int32_t tempy = floor_y;
10830 fakez=zc_max(0,zc_min(clk2start-clk2,clk2));
10831 floor_y = y;
10832 y=tempy-fakez;
10833 old_y = y;
10834 }
10835 else
10836 {
10837 762 int32_t tempy = floor_y;
10838
6/6
✓ Branch 0 taken 284 times.
✓ Branch 1 taken 478 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 756 times.
✓ Branch 4 taken 278 times.
✓ Branch 5 taken 478 times.
762 z=zc_max(0,zc_min(clk2start-clk2,clk2));
10839 762 floor_y = y;
10840 762 y=tempy-z;
10841 762 old_y = y;
10842 }
10843 762 }
10844
10845
4/4
✓ Branch 0 taken 284 times.
✓ Branch 1 taken 5574 times.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 261 times.
5858 if(stunclk && (clk&31)==1)
10846 261 clk=0;
10847
10848 5858 return enemy::animate(index);
10849 5984 }
10850
10851 1651 void eTektite::drawshadow(BITMAP *dest,bool translucent)
10852 {
10853
4/6
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 1538 times.
✓ Branch 2 taken 113 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 113 times.
1651 if(z<1 && fakez<1 && get_bit(quest_rules,qr_ENEMIESZAXIS))
10854 113 return;
10855
10856 1538 int32_t tempy=yofs;
10857 1538 int32_t fdiv = frate/4;
10858
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1538 times.
1538 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
10859
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1538 times.
1538 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
10860 1538 efrate:((clk>=(frate>>1))?1:0);
10861 1538 flip = 0;
10862 1538 shadowtile = wpnsbuf[spr_shadow].tile;
10863
10864
1/2
✓ Branch 0 taken 1538 times.
✗ Branch 1 not taken.
1538 if(get_bit(quest_rules,qr_NEWENEMYTILES))
10865 {
10866
2/2
✓ Branch 0 taken 912 times.
✓ Branch 1 taken 626 times.
1538 if(misc==0)
10867 {
10868 912 shadowtile+=f2;
10869 912 }
10870
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 385 times.
626 else if(misc!=1)
10871 385 shadowtile+=2;
10872 1538 }
10873 else
10874 {
10875 if(misc==0)
10876 {
10877 shadowtile += f2 ? 1 : 0;
10878 }
10879 else if(misc!=1)
10880 {
10881 ++shadowtile;
10882 }
10883 }
10884
10885 1538 yofs+=8;
10886
10887
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1538 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1538 if(!get_bit(quest_rules,qr_ENEMIESZAXIS) && misc==2)
10888 {
10889 yofs+=zc_max(0,zc_min(clk2start-clk2,clk2));
10890 }
10891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1538 times.
1538 if(!shadow_overpit(this))
10892 1538 enemy::drawshadow(dest,translucent);
10893 1538 yofs=tempy;
10894 1651 }
10895
10896 12141 void eTektite::draw(BITMAP *dest)
10897 {
10898 12141 update_enemy_frame();
10899 12141 enemy::draw(dest);
10900 12141 }
10901
10902 9 eItemFairy::eItemFairy(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10903 9 {
10904
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 step=zslongToFix(guysbuf[id&0xFFF].step*100);
10905 3 superman=1;
10906 3 dir=8;
10907 3 hxofs=1000;
10908 3 mainguy=false;
10909 3 count_enemy=false;
10910
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10911 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10912 // al_trace("Enemy txsz:%i\n", txsz);
10913
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = tysz; if ( tysz > 1 ) extend = 3; }
10914
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = hxsz;
10915
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = hysz;
10916
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = hzsz;
10917
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = hxofs;
10918
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = hyofs;
10919 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10920
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)xofs;
10921
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10922 {
10923 yofs = (int32_t)yofs; //This seems to be setting to +48 or something with any value set?! -Z
10924 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10925 }
10926
10927
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
10928 6 }
10929
10930 3001 bool eItemFairy::animate(int32_t index)
10931 {
10932
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3001 times.
3001 if(switch_hooked) return enemy::animate(index);
10933
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3001 times.
3001 if(dying)
10934 return Dead(index);
10935
10936 //if(clk>32)
10937 3001 misc=1;
10938 3001 bool w=watch;
10939 3001 watch=false;
10940 3001 variable_walk_8(misc?3:0,0,8,spw_floater);
10941 3001 watch=w;
10942
10943
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2988 times.
3001 if(clk==0)
10944 {
10945 13 removearmos(x,y,ffcactivated);
10946 13 }
10947
10948 3001 return enemy::animate(index);
10949 3001 }
10950
10951 6002 void eItemFairy::draw(BITMAP *dest)
10952 {
10953 //these are here to bypass compiler warnings about unused arguments
10954 6002 dest=dest;
10955 6002 }
10956
10957 ePeahat::ePeahat(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10958 {
10959 //floater_walk(int32_t rate,int32_t newclk,zfix ms,zfix ss,int32_t s,int32_t p, int32_t g)
10960 floater_walk(misc?rate:0, hrate, zslongToFix(dstep*100),zslongToFix(dstep*10), 10, dmisc16,dmisc17); // 80, 16);
10961 dir=8;
10962 movestatus=1;
10963 clk=0;
10964 step=0;
10965 //nets+720;
10966 SIZEflags = d->SIZEflags;
10967 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10968 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10969 // al_trace("Enemy txsz:%i\n", txsz);
10970 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10971 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10972 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10973 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10974 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10975 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10976 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10977 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10978 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10979 {
10980 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10981 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10982 }
10983
10984 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10985 }
10986
10987 bool ePeahat::animate(int32_t index)
10988 {
10989 if(switch_hooked) return enemy::animate(index);
10990 if(fallclk||drownclk) return enemy::animate(index);
10991 if(slide())
10992 {
10993 return false;
10994 }
10995
10996 if(dying)
10997 return Dead(index);
10998
10999 if(clk==0)
11000 {
11001 removearmos(x,y,ffcactivated);
11002 }
11003
11004 if(stunclk==0 && clk>96)
11005 misc=1;
11006
11007 if(!watch)
11008 floater_walk(misc?rate:0, hrate, zslongToFix(dstep*100),zslongToFix(dstep*10), 10, 80, 16);
11009
11010 if(get_bit(quest_rules,qr_ENEMIESZAXIS) && !(isSideViewGravity()))
11011 {
11012 if (moveflags & FLAG_USE_FAKE_Z) fakez=int32_t(step*1.1/((zslongToFix(dstep*10))*1.1));
11013 else z=int32_t(step*1.1/((zslongToFix(dstep*10))*1.1));
11014 }
11015
11016 if(watch && get_bit(quest_rules,qr_PEAHATCLOCKVULN))
11017 superman=0;
11018 else
11019 superman=(movestatus && !get_bit(quest_rules,qr_ENEMIESZAXIS)) ? 1 : 0;
11020 //stunclk=0; //Not sure what was going on here, or what was intended. Why was this set to 0? -Z
11021 if ( FFCore.getQuestHeaderInfo(vZelda) >= 0x250 )
11022 {
11023 if ( stunclk ) --stunclk;
11024 }
11025 else stunclk = 0; //Was probably this way in 2.10 quests. if not, then we never need to clear it. -Z
11026 //Pretty sure this was always an error. -Z ( 14FEB2019 )
11027
11028
11029 if(x<16) dir=right; //this is ugly, but so is moving or creating these guys with scripts.
11030
11031 return enemy::animate(index);
11032 }
11033
11034 void ePeahat::drawshadow(BITMAP *dest, bool translucent)
11035 {
11036 int32_t tempy=yofs;
11037 flip = 0;
11038 shadowtile = wpnsbuf[spr_shadow].tile+posframe;
11039
11040 if(!get_bit(quest_rules,qr_ENEMIESZAXIS))
11041 {
11042 yofs+=8;
11043 yofs+=int32_t(step/zslongToFix(dstep*10));
11044 }
11045 if(!shadow_overpit(this))
11046 enemy::drawshadow(dest,translucent);
11047 yofs=tempy;
11048 }
11049
11050 void ePeahat::draw(BITMAP *dest)
11051 {
11052 update_enemy_frame();
11053 enemy::draw(dest);
11054 }
11055
11056 int32_t ePeahat::takehit(weapon *w)
11057 {
11058 int32_t wpnId = w->id;
11059 int32_t enemyHitWeapon = w->parentitem;
11060
11061 if(dying || clk<0 || hclk>0)
11062 return 0;
11063
11064 if(superman && !(wpnId==wSBomb) // vulnerable to super bombs
11065 // fire boomerang, for nailing peahats
11066 && !(wpnId==wBrang && (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))>0))
11067 return 0;
11068
11069 // Time for a kludge...
11070 int32_t s = superman;
11071 superman = 0;
11072 int32_t ret = enemy::takehit(w);
11073 superman = s;
11074
11075 // Anyway...
11076 if(stunclk == 160)
11077 {
11078 clk2=0;
11079 movestatus=0;
11080 misc=0;
11081 clk=0;
11082 step=0;
11083 }
11084
11085 return ret;
11086 }
11087
11088 // auomatically kill off enemy (for rooms with ringleaders)
11089 void ePeahat::kickbucket()
11090 {
11091 hp=-1000; // don't call death_sfx()
11092 }
11093
11094 12 eLeever::eLeever(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
11095 12 {
11096 // if(d->misc1==0) { misc=-1; clk-=16; } //Line of Sight leevers
11097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(dmisc1==0)
11098 {
11099 4 misc=-1; //Line of Sight leevers
11100 4 clk-=16;
11101 4 }
11102 4 clk3 = 0;
11103 //nets+1460;
11104
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 temprule=(get_bit(quest_rules,qr_NEWENEMYTILES)) != 0;
11105 4 submerged = false;
11106 4 SIZEflags = d->SIZEflags;
11107
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
11108 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
11109 // al_trace("Enemy txsz:%i\n", txsz);
11110
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
11111
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
11112
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
11113
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
11114
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
11115
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
11116 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
11117
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
11118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
11119 {
11120 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
11121 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
11122 }
11123
11124
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
11125 8 }
11126
11127 bool eLeever::isSubmerged() const
11128 {
11129 Z_scripterrlog("misc is: %d\n", misc);
11130 return misc <= 0;
11131
11132 }
11133
11134 721 bool eLeever::animate(int32_t index)
11135 {
11136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 721 times.
721 if(switch_hooked) return enemy::animate(index);
11137
2/4
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 721 times.
721 if(fallclk||drownclk)
11138 {
11139 return enemy::animate(index);
11140 }
11141
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 703 times.
721 if(dying)
11142 18 return Dead(index);
11143
11144
2/2
✓ Branch 0 taken 690 times.
✓ Branch 1 taken 13 times.
703 if(clk==0)
11145 {
11146 13 removearmos(x,y,ffcactivated);
11147 13 }
11148
11149
4/4
✓ Branch 0 taken 489 times.
✓ Branch 1 taken 214 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 474 times.
703 if(clk>=0 && !slide())
11150 {
11151 // switch(d->misc1)
11152
1/2
✓ Branch 0 taken 474 times.
✗ Branch 1 not taken.
474 switch(dmisc1)
11153 {
11154 case 0: //line of sight
11155 case 2:
11156
5/8
✗ Branch 0 not taken.
✓ Branch 1 taken 208 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 186 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
474 switch(misc) //is this leever active
11157 {
11158 case -1: //submerged
11159 {
11160
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 208 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
208 if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk)) misc = 0;
11161
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 208 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
208 if((dmisc1==2)&&(zc_oldrand()&255))
11162 {
11163 break;
11164 }
11165
11166 208 int32_t active=0;
11167
11168
2/2
✓ Branch 0 taken 1003 times.
✓ Branch 1 taken 208 times.
1211 for(int32_t i=0; i<guys.Count(); i++)
11169 {
11170
4/4
✓ Branch 0 taken 795 times.
✓ Branch 1 taken 208 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 412 times.
1003 if(guys.spr(i)->id==id && (((enemy*)guys.spr(i))->misc>=0))
11171 {
11172 412 ++active;
11173 412 }
11174 1003 }
11175
11176
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 3 times.
208 if(active<((dmisc1==2)?1:2))
11177 {
11178 3 misc=0; //activate this one
11179 3 clk3=1; //This needs to be set so that it knows that it's being emerged of it's own will and not because it got stunned.
11180 3 }
11181 }
11182 208 break;
11183
11184 case 0:
11185 {
11186
11187
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
5 if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk))
11188 {
11189 misc=1;
11190 clk2=0;
11191 }
11192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 else if (clk3<=0)
11193 {
11194 misc = -1;
11195 break;
11196 }
11197 5 int32_t s=0;
11198
11199
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 5 times.
29 for(int32_t i=0; i<guys.Count(); i++)
11200 {
11201
4/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 2 times.
24 if(guys.spr(i)->id==id && ((enemy*)guys.spr(i))->misc==1)
11202 {
11203 2 ++s;
11204 2 }
11205 24 }
11206
11207
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 if(s>0)
11208 {
11209 2 break;
11210 }
11211
11212 3 int32_t d2=zc_oldrand()&1;
11213
11214
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(HeroDir()>=left)
11215 {
11216 d2+=2;
11217 }
11218
11219
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
3 if(canplace(d2) || canplace(d2^1))
11220 {
11221 3 misc=1;
11222 3 clk2=0;
11223 3 clk=0;
11224 3 }
11225 }
11226 3 break;
11227
11228 case 1:
11229
11230
3/8
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
51 if(++clk2>16||(!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk) && clk2>8)) misc=2;
11231
11232 51 break;
11233
11234 case 2:
11235
11236
3/8
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 21 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
24 if(++clk2>24||(!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk) && clk2>12)) misc=3;
11237
11238 24 break;
11239
11240 // case 3: if(stunclk) break; if(scored) dir^=1; if(!canmove(dir,false)) misc=4; else move((zfix)(d->step/100.0)); break;
11241 case 3:
11242
11243
3/6
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 186 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 186 times.
186 if(stunclk || frozenclock || watch) break;
11244
11245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 186 times.
186 if(scored) dir^=1;
11246
11247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 186 times.
186 if(!canmove(dir,false)) misc=4;
11248 186 else move(zslongToFix(dstep*100));
11249
11250 186 break;
11251
11252 case 4:
11253 if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk)) misc = 2;
11254 if(--clk2<=16)
11255 {
11256 misc=5;
11257 clk=8;
11258 }
11259
11260 break;
11261
11262 case 5:
11263 if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk)) misc = 1;
11264 if(--clk2<=0) misc=((dmisc1==2)?-1:0);
11265
11266 break;
11267 } // switch(misc)
11268
11269 474 break;
11270
11271 default: //random
11272 // step=d->misc3/100.0;
11273
11274 step=zslongToFix(dmisc3*100);
11275 if (get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) || (!watch && !stunclk)) ++clk2;
11276 else if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk))
11277 {
11278 if (clk2 < 48) clk2+=2;
11279 if (clk2 >= 300) clk2-=2;
11280 }
11281
11282 if(clk2<32) misc=1;
11283 else if(clk2<48) misc=2;
11284 else if(clk2<300)
11285 {
11286 /*if(misc==2 && (int32_t)(dmisc3*0.48)%8)
11287 {
11288 fix_coords();
11289 }*/
11290 misc=3;
11291 step = zslongToFix(dstep*100);
11292 }
11293 else if(clk2<316) misc=2;
11294 else if(clk2<412) misc=1;
11295 else if(clk2<540)
11296 {
11297 misc=0;
11298 step=0;
11299 }
11300 else clk2=0;
11301
11302 if(clk2==48) clk=0;
11303
11304 // variable_walk(d->rate, d->homing, 0);
11305 variable_walk(rate, homing, 0);
11306 } // switch(dmisc1)
11307 474 }
11308
11309 703 hxofs=(misc>=2)?0:1000;
11310 703 return enemy::animate(index);
11311 721 }
11312
11313 4 bool eLeever::canplace(int32_t d2)
11314 {
11315 4 int32_t nx=HeroX();
11316 4 int32_t ny=HeroY();
11317
11318
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(d2<left) ny&=0xF0;
11319 else nx&=0xF0;
11320
11321
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 switch(d2)
11322 {
11323 // case up: ny-=((d->misc1==0)?32:48); break;
11324 // case down: ny+=((d->misc1==0)?32:48); if(ny-HeroY()<32) ny+=((d->misc1==0)?16:0); break;
11325 // case left: nx-=((d->misc1==0)?32:48); break;
11326 // case right: nx+=((d->misc1==0)?32:48); if(nx-HeroX()<32) nx+=((d->misc1==0)?16:0); break;
11327 case up:
11328
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 ny-=((dmisc1==0||dmisc1==2)?32:48);
11329 1 break;
11330
11331 case down:
11332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 ny+=((dmisc1==0||dmisc1==2)?32:48);
11333
11334
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 if(ny-HeroY()<32) ny+=((dmisc1==0||dmisc1==2)?16:0);
11335
11336 3 break;
11337
11338 case left:
11339 nx-=((dmisc1==0||dmisc1==2)?32:48);
11340 break;
11341
11342 case right:
11343 nx+=((dmisc1==0||dmisc1==2)?32:48);
11344
11345 if(nx-HeroX()<32) nx+=((dmisc1==0||dmisc1==2)?16:0);
11346
11347 break;
11348 }
11349
11350
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
4 if(m_walkflag(nx,ny,spw_halfstep, dir)||m_walkflag(nx,ny-8,spw_halfstep, dir)) /*none*/
11351 1 return false;
11352
11353
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(d2>=left)
11354 if(m_walkflag(HeroX(),HeroY(),spw_halfstep, dir)||m_walkflag(HeroX(),HeroY()-8,spw_halfstep, dir)) /*none*/
11355 return false;
11356
11357 3 x=nx;
11358 3 y=ny;
11359 3 dir=d2^1;
11360 3 return true;
11361 4 }
11362
11363 721 void eLeever::draw(BITMAP *dest)
11364 {
11365 // cs=d->cset;
11366 721 cs=dcset;
11367 721 update_enemy_frame();
11368
2/4
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 721 times.
721 if(!fallclk&&!drownclk)
11369 {
11370
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 427 times.
721 switch(misc)
11371 {
11372 case -1:
11373 case 0:
11374 427 return;
11375 }
11376 294 }
11377
11378 294 enemy::draw(dest);
11379 721 }
11380
11381 48 eWallM::eWallM(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
11382 48 {
11383 //zprint2("eWallM::eWallM\n");
11384 16 hashero=false;
11385 //nets+1000;
11386 16 SIZEflags = d->SIZEflags;
11387
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
11388 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
11389 // al_trace("Enemy txsz:%i\n", txsz);
11390
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
11391
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
11392
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
11393
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
11394
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
11395
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
11396 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
11397
1/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
11398
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
11399 {
11400 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
11401 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
11402 }
11403
11404
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
11405 32 }
11406
11407 8285 bool eWallM::animate(int32_t index)
11408 {
11409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8285 times.
8285 if(switch_hooked) return enemy::animate(index);
11410
2/4
✓ Branch 0 taken 8285 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8285 times.
8285 if(fallclk||drownclk)
11411 {
11412 return enemy::animate(index);
11413 }
11414
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 8123 times.
8285 if(dying)
11415 162 return Dead(index);
11416
11417
2/2
✓ Branch 0 taken 7670 times.
✓ Branch 1 taken 453 times.
8123 if(clk==0)
11418 {
11419 453 removearmos(x,y,ffcactivated);
11420 453 }
11421
11422 8123 hxofs=1000;
11423
2/2
✓ Branch 0 taken 3051 times.
✓ Branch 1 taken 5072 times.
8123 if(misc==0) //inside wall, ready to spawn?
11424 {
11425 //zprint2("Wallmaster is ready to spawn, clk is: %d\n",clk);
11426 //zprint2("frame is: %d\n",frame);
11427 //zprint2("wallm_load_clk is: %d\n",wallm_load_clk);
11428
4/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3378 times.
✓ Branch 2 taken 267 times.
✓ Branch 3 taken 1427 times.
5072 if(frame-wallm_load_clk>80 && clk>=0)
11429 {
11430 //zprint2("getting wall\n");
11431 1427 int32_t wall=hero_on_wall();
11432 //zprint2("Wallmaster wall is %d\n",wall);
11433 1427 int32_t wallm_cnt=0;
11434
11435
2/2
✓ Branch 0 taken 11411 times.
✓ Branch 1 taken 1427 times.
12838 for(int32_t i=0; i<guys.Count(); i++)
11436
2/2
✓ Branch 0 taken 899 times.
✓ Branch 1 taken 10512 times.
21923 if(((enemy*)guys.spr(i))->family==eeWALLM)
11437 {
11438 10512 int32_t m=((enemy*)guys.spr(i))->misc;
11439
11440
4/4
✓ Branch 0 taken 1764 times.
✓ Branch 1 taken 8748 times.
✓ Branch 2 taken 1762 times.
✓ Branch 3 taken 2 times.
10512 if(m && ((enemy*)guys.spr(i))->clk3==(wall^1))
11441 {
11442 2 ++wallm_cnt;
11443 2 }
11444 10512 }
11445
11446
2/2
✓ Branch 0 taken 1414 times.
✓ Branch 1 taken 13 times.
1427 if(wall>0)
11447 {
11448 13 --wall;
11449 13 misc=1; //emerging from the wall?
11450 //zprint2("Wallmaster is emerging\n");
11451 13 clk2=0;
11452 13 clk3=wall^1;
11453 13 wallm_load_clk=frame;
11454
11455
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 9 times.
13 if(wall<=down)
11456 {
11457
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if(HeroDir()==left)
11458 1 dir=right;
11459 else
11460 3 dir=left;
11461 4 }
11462 else
11463 {
11464
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
9 if(HeroDir()==up)
11465 2 dir=down;
11466 else
11467 7 dir=up;
11468 }
11469
11470
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 5 times.
13 switch(wall)
11471 {
11472 case up:
11473 3 y=0;
11474 3 break;
11475
11476 case down:
11477 1 y=160;
11478 1 break;
11479
11480 case left:
11481 4 x=0;
11482 4 break;
11483
11484 case right:
11485 5 x=240;
11486 5 break;
11487 }
11488
11489 //zprint2("Wallmaster (p1) x is %d\n",x);
11490 //zprint2("Wallmaster (p1) y is %d\n",y);
11491
11492
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
13 switch(dir)
11493 {
11494 case up:
11495 7 y=(HeroY()+48-(wallm_cnt&1)*12);
11496 7 flip=wall&1;
11497 7 break;
11498
11499 case down:
11500 2 y=(HeroY()-48+(wallm_cnt&1)*12);
11501 2 flip=((wall&1)^1)+2;
11502 2 break;
11503
11504 case left:
11505 3 x=(HeroX()+48-(wallm_cnt&1)*12);
11506 3 flip=(wall==up?2:0)+1;
11507 3 break;
11508
11509 case right:
11510 1 x=(HeroX()-48+(wallm_cnt&1)*12);
11511 1 flip=(wall==up?2:0);
11512 1 break;
11513 }
11514
11515 //zprint2("Wallmaster (p2) x is %d\n",x);
11516 //zprint2("Wallmaster (p2) y is %d\n",y);
11517 13 }
11518 1427 }
11519 5072 }
11520 else
11521 3051 wallm_crawl();
11522
11523 8123 return enemy::animate(index);
11524 8285 }
11525
11526 3051 void eWallM::wallm_crawl()
11527 {
11528 3051 bool w=watch;
11529 3051 hxofs=0;
11530
11531
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 3035 times.
3051 if(slide())
11532 {
11533 16 return;
11534 }
11535
11536 // if(dying || watch || (!hashero && stunclk))
11537
5/8
✓ Branch 0 taken 3035 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3035 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1859 times.
✓ Branch 5 taken 1176 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1859 times.
3035 if(dying || (!hashero && ( stunclk || frozenclock )))
11538 {
11539 1176 return;
11540 }
11541
11542 1859 watch=false;
11543 1859 ++clk2;
11544 // Misc1: slightly different movement
11545 //zprint2("wallmaster crawl\n");
11546 //zprint2("wallmaster tmpdstep is %d\n",tmpdstep);
11547 1859 float tmpmisc3 = ((40.0/(int32_t)dstep)*40);
11548
11549 //int32_t tmpmisc = int32_t((40.0/dstep)*40);
11550 //zprint2("wallmaster crawl tmpmisc is: %d\n", tmpmisc);
11551 //zprint2("wallmaster crawl tmpmisc4 is: %d\n", tmpmisc4);
11552
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1859 times.
1859 misc=(clk2/(dmisc1==1?40:(int32_t)tmpmisc3))+1;
11553 //zprint2("wallmaster crawl misc is: %d\n", misc);
11554
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1859 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1859 if(w&&misc>=3&&misc<=5)
11555 {
11556 --clk2;
11557 }
11558
11559
4/4
✓ Branch 0 taken 709 times.
✓ Branch 1 taken 988 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 2 times.
1859 switch(misc)
11560 {
11561 case 1:
11562 case 2:
11563 988 zc_swap(dir,clk3);
11564 988 move(step);
11565 988 zc_swap(dir,clk3);
11566 988 break;
11567
11568 case 3:
11569 case 4:
11570 case 5:
11571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 709 times.
709 if(w)
11572 {
11573 watch=w;
11574 return;
11575 }
11576
11577 709 move(step);
11578 709 break;
11579
11580 case 6:
11581 case 7:
11582 160 zc_swap(dir,clk3);
11583 160 dir^=1;
11584 160 move(step);
11585 160 dir^=1;
11586 160 zc_swap(dir,clk3);
11587 160 break;
11588
11589 default:
11590 2 misc=0;
11591 2 break;
11592 }
11593
11594 1859 watch=w;
11595 3051 }
11596
11597 void eWallM::grabhero()
11598 {
11599 hashero=true;
11600 superman=1;
11601 }
11602
11603 8285 void eWallM::draw(BITMAP *dest)
11604 {
11605 8285 dummy_bool[1]=hashero;
11606 8285 update_enemy_frame();
11607
11608
4/6
✓ Branch 0 taken 5072 times.
✓ Branch 1 taken 3213 times.
✓ Branch 2 taken 5072 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5072 times.
8285 if(misc>0 || fallclk||drownclk)
11609 {
11610 3213 masked_draw(dest,16,playing_field_offset+16,224,144);
11611 3213 }
11612
11613 // enemy::draw(dest);
11614 // tile = clk&8 ? 128:129;
11615 8285 }
11616
11617 bool eWallM::isSubmerged() const
11618 {
11619 return ( !misc );
11620 }
11621
11622 eTrap::eTrap(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
11623 {
11624 ox=x; //original x
11625 oy=y; //original y
11626 if(get_bit(quest_rules,qr_TRAPPOSFIX))
11627 {
11628 yofs = (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
11629 }
11630
11631 mainguy=false;
11632 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
11633 //nets+420;
11634 dummy_int[1]=0;
11635 SIZEflags = d->SIZEflags;
11636 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
11637 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
11638 // al_trace("Enemy txsz:%i\n", txsz);
11639 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
11640 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
11641 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
11642 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
11643 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
11644 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
11645 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
11646 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
11647 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
11648 {
11649 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
11650 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
11651 }
11652
11653 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
11654 }
11655
11656 bool eTrap::animate(int32_t index)
11657 {
11658 if(switch_hooked) return enemy::animate(index);
11659 if(fallclk||drownclk) return enemy::animate(index);
11660 if(clk<0)
11661 return enemy::animate(index);
11662
11663 if(clk==0)
11664 {
11665 removearmos(x,y,ffcactivated);
11666 }
11667
11668 if(misc==0) // waiting
11669 {
11670 ox = x;
11671 oy = y;
11672 double _MSVC2022_tmp1, _MSVC2022_tmp2;
11673 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
11674
11675 if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
11676 {
11677 dir=down;
11678 }
11679 else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
11680 {
11681 dir=right;
11682 }
11683 else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
11684 {
11685 dir=up;
11686 }
11687 else
11688 {
11689 dir=left;
11690 }
11691
11692 int32_t d2=lined_up(15,true);
11693
11694 if(((d2<left || d2 > right) && (dmisc1==1)) ||
11695 ((d2>down) && (dmisc1==2)) ||
11696 ((d2>right) && (!dmisc1)) ||
11697 ((d2<l_up) && (dmisc1==4)) ||
11698 ((d2!=r_up) && (d2!=l_down) && (dmisc1==6)) ||
11699 ((d2!=l_up) && (d2!=r_down) && (dmisc1==8)))
11700 {
11701 d2=-1;
11702 }
11703
11704 if(d2!=-1 && trapmove(d2))
11705 {
11706 dir=d2;
11707 misc=1;
11708 clk2=(dir==down)?3:0;
11709 }
11710 }
11711
11712 if(misc==1) // charging
11713 {
11714 clk2=(clk2+1)&3;
11715 step=(clk2==3)?1:2;
11716
11717 if(!trapmove(dir) || clip())
11718 {
11719 misc=2;
11720
11721 if(dir<l_up)
11722 {
11723 dir=dir^1;
11724 }
11725 else
11726 {
11727 dir=dir^3;
11728 }
11729 }
11730 else
11731 {
11732 sprite::move(step);
11733 }
11734 }
11735
11736 if(misc==2) // retreating
11737 {
11738 step=(++clk2&1)?1:0;
11739
11740 switch(dir)
11741 {
11742 case up:
11743 if(int32_t(y)<=oy) goto trap_rest;
11744 else sprite::move(step);
11745
11746 break;
11747
11748 case left:
11749 if(int32_t(x)<=ox) goto trap_rest;
11750 else sprite::move(step);
11751
11752 break;
11753
11754 case down:
11755 if(int32_t(y)>=oy) goto trap_rest;
11756 else sprite::move(step);
11757
11758 break;
11759
11760 case right:
11761 if(int32_t(x)>=ox) goto trap_rest;
11762 else sprite::move(step);
11763
11764 break;
11765
11766 case l_up:
11767 if(int32_t(x)<=ox && int32_t(y)<=oy) goto trap_rest;
11768 else sprite::move(step);
11769
11770 break;
11771
11772 case r_up:
11773 if(int32_t(x)>=ox && int32_t(y)<=oy) goto trap_rest;
11774 else sprite::move(step);
11775
11776 break;
11777
11778 case l_down:
11779 if(int32_t(x)<=ox && int32_t(y)>=oy) goto trap_rest;
11780 else sprite::move(step);
11781
11782 break;
11783
11784 case r_down:
11785 if(int32_t(x)>=ox && int32_t(y)>=oy) goto trap_rest;
11786 else sprite::move(step);
11787
11788 break;
11789 trap_rest:
11790 {
11791 x=ox;
11792 y=oy;
11793 misc=0;
11794 }
11795 }
11796 }
11797
11798 return enemy::animate(index);
11799 }
11800
11801 bool eTrap::trapmove(int32_t ndir)
11802 {
11803 if(get_bit(quest_rules,qr_MEANTRAPS))
11804 {
11805 if(tmpscr->flags2&fFLOATTRAPS)
11806 return canmove(ndir,(zfix)1,spw_floater, 0, 0, 15, 15,false);
11807
11808 return canmove(ndir,(zfix)1,spw_water, 0, 0, 15, 15,false);
11809 }
11810
11811 if(oy==80 && !(ndir==left || ndir == right))
11812 return false;
11813
11814 if(ox==128 && !(ndir==up || ndir==down))
11815 return false;
11816
11817 if(oy<80 && ndir==up)
11818 return false;
11819
11820 if(oy>80 && ndir==down)
11821 return false;
11822
11823 if(ox<128 && ndir==left)
11824 return false;
11825
11826 if(ox>128 && ndir==right)
11827 return false;
11828
11829 if(ox<128 && oy<80 && ndir==l_up)
11830 return false;
11831
11832 if(ox<128 && oy>80 && ndir==l_down)
11833 return false;
11834
11835 if(ox>128 && oy<80 && ndir==r_up)
11836 return false;
11837
11838 if(ox>128 && oy>80 && ndir==r_down)
11839 return false;
11840
11841 return true;
11842 }
11843
11844 bool eTrap::clip()
11845 {
11846 if(get_bit(quest_rules,qr_MEANPLACEDTRAPS))
11847 {
11848 switch(dir)
11849 {
11850 case up:
11851 if(y<=0) return true;
11852
11853 break;
11854
11855 case down:
11856 if(y>=160) return true;
11857
11858 break;
11859
11860 case left:
11861 if(x<=0) return true;
11862
11863 break;
11864
11865 case right:
11866 if(x>=240) return true;
11867
11868 break;
11869
11870 case l_up:
11871 if(y<=0||x<=0) return true;
11872
11873 break;
11874
11875 case l_down:
11876 if(y>=160||x<=0) return true;
11877
11878 break;
11879
11880 case r_up:
11881 if(y<=0||x>=240) return true;
11882
11883 break;
11884
11885 case r_down:
11886 if(y>=160||x>=240) return true;
11887
11888 break;
11889 }
11890
11891 return false;
11892 }
11893 else
11894 {
11895 switch(dir)
11896 {
11897 case up:
11898 if(oy>80 && y<=86) return true;
11899
11900 break;
11901
11902 case down:
11903 if(oy<80 && y>=80) return true;
11904
11905 break;
11906
11907 case left:
11908 if(ox>128 && x<=124) return true;
11909
11910 break;
11911
11912 case right:
11913 if(ox<120 && x>=116) return true;
11914
11915 break;
11916
11917 case l_up:
11918 if(oy>80 && y<=86 && ox>128 && x<=124) return true;
11919
11920 break;
11921
11922 case l_down:
11923 if(oy<80 && y>=80 && ox>128 && x<=124) return true;
11924
11925 break;
11926
11927 case r_up:
11928 if(oy>80 && y<=86 && ox<120 && x>=116) return true;
11929
11930 break;
11931
11932 case r_down:
11933 if(oy<80 && y>=80 && ox<120 && x>=116) return true;
11934
11935 break;
11936 }
11937
11938 return false;
11939 }
11940 }
11941
11942 void eTrap::draw(BITMAP *dest)
11943 {
11944 update_enemy_frame();
11945 enemy::draw(dest);
11946 }
11947
11948 int32_t eTrap::takehit(weapon*)
11949 {
11950 return 0;
11951 }
11952
11953 eTrap2::eTrap2(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
11954 {
11955 lasthit=-1;
11956 lasthitclk=0;
11957 mainguy=false;
11958 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
11959 step=2;
11960 if(dmisc1==1 || (dmisc1==0 && zc_oldrand()&2))
11961 {
11962 dir=(x<=112)?right:left;
11963 }
11964 else
11965 {
11966 dir=(y<=72)?down:up;
11967 }
11968
11969 if(get_bit(quest_rules,qr_TRAPPOSFIX))
11970 {
11971 yofs = (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
11972 }
11973
11974 //nets+((id==eTRAP_LR)?540:520);
11975 dummy_int[1]=0;
11976 SIZEflags = d->SIZEflags;
11977 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
11978 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
11979 // al_trace("Enemy txsz:%i\n", txsz);
11980 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
11981 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
11982 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
11983 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
11984 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
11985 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
11986 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
11987 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
11988 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
11989 {
11990 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
11991 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
11992 }
11993
11994 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
11995 }
11996
11997 bool eTrap2::animate(int32_t index)
11998 {
11999 if(switch_hooked) return enemy::animate(index);
12000 if(fallclk||drownclk) return enemy::animate(index);
12001 if(clk<0)
12002 return enemy::animate(index);
12003
12004 if(clk==0)
12005 {
12006 removearmos(x,y,ffcactivated);
12007 }
12008
12009 if(!get_bit(quest_rules,qr_PHANTOMPLACEDTRAPS))
12010 {
12011 if(lasthitclk>0)
12012 {
12013 --lasthitclk;
12014 }
12015 else
12016 {
12017 lasthit=-1;
12018 }
12019
12020 bool hitenemy=false;
12021
12022 for(int32_t j=0; j<guys.Count(); j++)
12023 {
12024 if((j!=index) && (lasthit!=j))
12025 {
12026 if(hit(guys.spr(j)))
12027 {
12028 lasthit=j;
12029 lasthitclk=10;
12030 hitenemy=true;
12031 guys.spr(j)->lasthit=index;
12032 guys.spr(j)->lasthitclk=10;
12033 // guys.spr(j)->dir=guys.spr(j)->dir^1;
12034 }
12035 }
12036 }
12037
12038 if(!trapmove(dir) || clip() || hitenemy)
12039 {
12040 if(!trapmove(dir) || clip())
12041 {
12042 lasthit=-1;
12043 lasthitclk=0;
12044 }
12045
12046 if(get_bit(quest_rules,qr_MORESOUNDS))
12047 sfx(WAV_ZN1TAP,pan(int32_t(x)));
12048
12049 dir=dir^1;
12050 }
12051
12052 sprite::move(step);
12053 }
12054 else
12055 {
12056 if(!trapmove(dir) || clip())
12057 {
12058 if(get_bit(quest_rules,qr_MORESOUNDS))
12059 sfx(WAV_ZN1TAP,pan(int32_t(x)));
12060
12061 dir=dir^1;
12062 }
12063
12064 sprite::move(step);
12065 }
12066
12067 return enemy::animate(index);
12068 }
12069
12070 bool eTrap2::trapmove(int32_t ndir)
12071 {
12072 if(tmpscr->flags2&fFLOATTRAPS)
12073 return canmove(ndir,(zfix)1,spw_floater, 0, 0, 15, 15,false);
12074
12075 return canmove(ndir,(zfix)1,spw_water, 0, 0, 15, 15,false);
12076 }
12077
12078 bool eTrap2::clip()
12079 {
12080 switch(dir)
12081 {
12082 case up:
12083 if(y<=0) return true;
12084
12085 break;
12086
12087 case down:
12088 if(y>=160) return true;
12089
12090 break;
12091
12092 case left:
12093 if(x<=0) return true;
12094
12095 break;
12096
12097 case right:
12098 if(x>=240) return true;
12099
12100 break;
12101 }
12102
12103 return false;
12104 }
12105
12106 void eTrap2::draw(BITMAP *dest)
12107 {
12108 update_enemy_frame();
12109 enemy::draw(dest);
12110 }
12111
12112 int32_t eTrap2::takehit(weapon*)
12113 {
12114 return 0;
12115 }
12116
12117 eRock::eRock(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12118 {
12119 //do not show "enemy appering" anim -DD
12120 clk=0;
12121 mainguy=false;
12122 clk2=-14;
12123 //Enemy Editor Size Tab
12124 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12125 else hxofs = -2;
12126 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12127 else hyofs = -2;
12128 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
12129 else hxsz = 20;
12130 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
12131 else hysz=20;
12132
12133 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12134 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12135 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
12136 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
12137 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12138 {
12139 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12140 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12141 }
12142
12143 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
12144 //nets+1640;
12145 }
12146
12147 bool eRock::animate(int32_t index)
12148 {
12149 if(switch_hooked) return enemy::animate(index);
12150 if(fallclk||drownclk) return enemy::animate(index);
12151 if(dying)
12152 return Dead(index);
12153
12154 if(clk==0)
12155 {
12156 removearmos(x,y,ffcactivated);
12157 }
12158
12159 if(++clk2==0) // start it
12160 {
12161 x=zc_oldrand()&0xF0;
12162 y=0;
12163 clk3=0;
12164 clk2=zc_oldrand()&15;
12165 }
12166
12167 if(clk2>16) // move it
12168 {
12169 if(clk3<=0) // start bounce
12170 {
12171 dir=zc_oldrand()&1;
12172
12173 if(x<32) dir=1;
12174
12175 if(x>208) dir=0;
12176 }
12177
12178 if(clk3<13+16)
12179 {
12180 x += dir ? 1 : -1; //right, left
12181 dummy_int[1]=dir;
12182
12183 if(clk3<2)
12184 {
12185 y-=2; //up
12186 dummy_int[2]=(dummy_int[1]==1)?r_up:l_up;
12187 }
12188 else if(clk3<5)
12189 {
12190 y--; //up
12191 dummy_int[2]=(dummy_int[1]==1)?r_up:l_up;
12192 }
12193 else if(clk3<8)
12194 {
12195 dummy_int[2]=(dummy_int[1]==1)?right:left;
12196 }
12197 else if(clk3<11)
12198 {
12199 y++; //down
12200 dummy_int[2]=(dummy_int[1]==1)?r_down:l_down;
12201 }
12202 else
12203 {
12204 y+=2; //down
12205 dummy_int[2]=(dummy_int[1]==1)?r_down:l_down;
12206 }
12207
12208 ++clk3;
12209 }
12210 else if(y<176)
12211 clk3=0; // next bounce
12212 else
12213 clk2 = -(zc_oldrand()&63); // back to top
12214 }
12215
12216 return enemy::animate(index);
12217 }
12218
12219 void eRock::drawshadow(BITMAP *dest, bool translucent)
12220 {
12221 if(clk2>=0)
12222 {
12223 int32_t tempy=yofs;
12224 flip = 0;
12225 int32_t fdiv = frate/4;
12226 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
12227 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
12228 efrate:((clk>=(frate>>1))?1:0);
12229 shadowtile = wpnsbuf[spr_shadow].tile+f2;
12230
12231 yofs+=8;
12232 yofs+=zc_max(0,zc_min(29-clk3,clk3));
12233 if(!shadow_overpit(this))
12234 enemy::drawshadow(dest, translucent);
12235 yofs=tempy;
12236 }
12237 }
12238
12239 void eRock::draw(BITMAP *dest)
12240 {
12241 if(clk2>=0 || fallclk||drownclk)
12242 {
12243 int32_t tempdir=dir;
12244 dir=dummy_int[2];
12245 update_enemy_frame();
12246 enemy::draw(dest);
12247 dir=tempdir;
12248 }
12249 }
12250
12251 int32_t eRock::takehit(weapon*)
12252 {
12253 return 0;
12254 }
12255
12256 eBoulder::eBoulder(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12257 {
12258 clk=0;
12259 mainguy=false;
12260 clk2=-14;
12261 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12262 else hxofs= -10;
12263 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12264 else hyofs=-10;
12265 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
12266 else hxsz=36;
12267 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
12268 else hysz=36;
12269 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
12270 else hzsz=16; //can't be jumped
12271
12272 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12273 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12274 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
12275 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
12276 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12277 {
12278 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12279 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12280 }
12281
12282 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
12283 //nets+1680;
12284 }
12285
12286 bool eBoulder::animate(int32_t index)
12287 {
12288 if(switch_hooked) return enemy::animate(index);
12289 if(fallclk||drownclk) return enemy::animate(index);
12290 if(dying)
12291 return Dead(index);
12292
12293 if(clk==0)
12294 {
12295 removearmos(x,y,ffcactivated);
12296 }
12297
12298 zfix *vert;
12299 vert = (moveflags & FLAG_USE_FAKE_Z) ? &fakez : get_bit(quest_rules,qr_ENEMIESZAXIS) ? &z : &y;
12300
12301 if(++clk2==0) // start it
12302 {
12303 x=zc_oldrand()&0xF0;
12304 y=-32;
12305 clk3=0;
12306 clk2=zc_oldrand()&15;
12307 }
12308
12309 if(clk2>16) // move it
12310 {
12311 if(clk3<=0) // start bounce
12312 {
12313 dir=zc_oldrand()&1;
12314
12315 if(x<32) dir=1;
12316
12317 if(x>208) dir=0;
12318 }
12319
12320 if(clk3<13+16)
12321 {
12322 x += dir ? 1 : -1; //right, left
12323 dummy_int[1]=dir;
12324
12325 if(clk3<2)
12326 {
12327 y-=2; //up
12328 dummy_int[2]=(dummy_int[1]==1)?r_up:l_up;
12329 }
12330 else if(clk3<5)
12331 {
12332 y--; //up
12333 dummy_int[2]=(dummy_int[1]==1)?r_up:l_up;
12334 }
12335 else if(clk3<8)
12336 {
12337 dummy_int[2]=(dummy_int[1]==1)?right:left;
12338 }
12339 else if(clk3<11)
12340 {
12341 y++; //down
12342 dummy_int[2]=(dummy_int[1]==1)?r_down:l_down;
12343 }
12344 else
12345 {
12346 y+=2; //down
12347 dummy_int[2]=(dummy_int[1]==1)?r_down:l_down;
12348 }
12349
12350 ++clk3;
12351 }
12352 else if(y<176)
12353 clk3=0; // next bounce
12354 else
12355 clk2 = -(zc_oldrand()&63); // back to top
12356 }
12357
12358 return enemy::animate(index);
12359 }
12360
12361 void eBoulder::drawshadow(BITMAP *dest, bool translucent)
12362 {
12363 if(clk2>=0)
12364 {
12365 int32_t tempy=yofs;
12366 flip = 0;
12367 int32_t f2=((clk<<2)/frate)<<1;
12368 shadowtile = wpnsbuf[spr_shadow].tile+f2;
12369 yofs+=zc_max(0,zc_min(29-clk3,clk3));
12370
12371 yofs+=8;
12372 xofs-=8;
12373 if(!shadow_overpit(this))
12374 enemy::drawshadow(dest, translucent);
12375 xofs+=16;
12376 ++shadowtile;
12377 if(!shadow_overpit(this))
12378 enemy::drawshadow(dest, translucent);
12379 yofs+=16;
12380 shadowtile+=20;
12381 if(!shadow_overpit(this))
12382 enemy::drawshadow(dest, translucent);
12383 xofs-=16;
12384 --shadowtile;
12385 if(!shadow_overpit(this))
12386 enemy::drawshadow(dest, translucent);
12387 xofs+=8;
12388 yofs=tempy;
12389 }
12390 }
12391
12392 void eBoulder::draw(BITMAP *dest)
12393 {
12394 if(clk2>=0 || fallclk||drownclk)
12395 {
12396 int32_t tempdir=dir;
12397 dir=dummy_int[2];
12398 update_enemy_frame();
12399 dir=tempdir;
12400 xofs-=8;
12401 yofs-=8;
12402 drawblock(dest,15);
12403 xofs+=8;
12404 yofs+=8;
12405 // enemy::draw(dest);
12406 }
12407 }
12408
12409 int32_t eBoulder::takehit(weapon*)
12410 {
12411 return 0;
12412 }
12413
12414 18 eProjectile::eProjectile(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk),
12415
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 minRange(get_bit(quest_rules, qr_BROKENSTATUES) ? 0 : Clk)
12416 18 {
12417 /* fixing
12418 hp=1;
12419 */
12420 6 mainguy=false;
12421
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
12422 6 hclk=clk; // the "no fire" range
12423 6 clk=0;
12424 6 clk3=96;
12425 6 timer=0;
12426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(o_tile==0)
12427 {
12428 6 superman=1;
12429 6 hxofs=1000;
12430 6 }
12431 6 SIZEflags = d->SIZEflags;
12432
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12433 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12434 // al_trace("Enemy txsz:%i\n", txsz);
12435
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12436
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
12437
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
12438
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
12439
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12440
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12441 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
12442
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
12443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12444 {
12445 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12446 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12447 }
12448
12449
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
12450 12 }
12451
12452 412 bool eProjectile::animate(int32_t index)
12453 {
12454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 412 times.
412 if(switch_hooked) return enemy::animate(index);
12455
2/4
✓ Branch 0 taken 412 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 412 times.
412 if(fallclk||drownclk) return enemy::animate(index);
12456
2/2
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 6 times.
412 if(clk==0)
12457 {
12458 6 removearmos(x,y,ffcactivated);
12459 6 }
12460
12461 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12462 412 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
12463
12464
3/4
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 246 times.
✓ Branch 2 taken 166 times.
✗ Branch 3 not taken.
412 if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
12465 {
12466 dir=down;
12467 }
12468
4/4
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 166 times.
✓ Branch 2 taken 166 times.
✓ Branch 3 taken 80 times.
412 else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
12469 {
12470 80 dir=right;
12471 80 }
12472
3/4
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 166 times.
✓ Branch 2 taken 166 times.
✗ Branch 3 not taken.
332 else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
12473 {
12474 dir=up;
12475 }
12476 else
12477 {
12478 332 dir=left;
12479 }
12480
12481
3/4
✓ Branch 0 taken 412 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 99 times.
✓ Branch 3 taken 313 times.
412 if(!stunclk && ++clk3>80)
12482 {
12483
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 313 times.
313 if(dmisc1==9) // Breath type
12484 {
12485 if(timer==0)
12486 {
12487 unsigned r=zc_oldrand();
12488
12489 if(!(r&63))
12490 {
12491 timer=zc_oldrand()%50+50;
12492 }
12493 }
12494
12495 if(timer>0)
12496 {
12497 if(timer%4==0)
12498 {
12499 FireBreath(false);
12500 }
12501
12502 if(--timer==0)
12503 {
12504 clk3=0;
12505 }
12506 }
12507 }
12508
12509 else // Not breath type
12510 {
12511 313 unsigned r=zc_oldrand();
12512
12513
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 310 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
313 if(!(r&63) && !HeroInRange(minRange))
12514 {
12515 3 FireWeapon();
12516
12517
1/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if(get_bit(quest_rules, qr_BROKENSTATUES)==0 &&
12518
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 ((wpn==ewFireball || wpn==ewFireball2) || dmisc1==e1tNORMAL))
12519 {
12520
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(!((r>>7)&15))
12521 {
12522 x-=4;
12523 FireWeapon();
12524 x+=4;
12525 }
12526 3 }
12527
12528 3 clk3=0;
12529 3 }
12530 }
12531 313 }
12532
12533 412 return enemy::animate(index);
12534 412 }
12535
12536 412 void eProjectile::draw(BITMAP *dest)
12537 {
12538 412 update_enemy_frame();
12539 412 enemy::draw(dest);
12540 412 }
12541
12542 eTrigger::eTrigger(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12543 {
12544 hxofs=1000;
12545 }
12546
12547 void eTrigger::draw(BITMAP *dest)
12548 {
12549 update_enemy_frame();
12550 enemy::draw(dest);
12551 }
12552
12553 void eTrigger::death_sfx()
12554 {
12555 //silent death
12556 }
12557
12558 eNPC::eNPC(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12559 {
12560 o_tile+=wpnsbuf[iwNPCs].tile;
12561 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
12562 SIZEflags = d->SIZEflags;
12563 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12564 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12565 // al_trace("Enemy txsz:%i\n", txsz);
12566 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12567 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
12568 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
12569 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
12570 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12571 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12572 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
12573 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
12574 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12575 {
12576 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12577 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12578 }
12579
12580 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
12581 }
12582
12583 bool eNPC::animate(int32_t index)
12584 {
12585 if(switch_hooked) return enemy::animate(index);
12586 if(dying)
12587 return Dead(index);
12588
12589 if(clk==0)
12590 {
12591 removearmos(x,y,ffcactivated);
12592 }
12593
12594 switch(dmisc2)
12595 {
12596 case 0:
12597 {
12598 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12599 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
12600
12601 if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
12602 {
12603 dir=down;
12604 }
12605
12606 else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
12607 {
12608 dir=right;
12609 }
12610 else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/8)))
12611 {
12612 dir=up;
12613 }
12614 else
12615 {
12616 dir=left;
12617 }
12618 }
12619 break;
12620
12621 case 1:
12622 halting_walk(rate, homing, 0, hrate, 48);
12623
12624 if(clk2==1 && (misc < dmisc1) && !(zc_oldrand()&15))
12625 {
12626 newdir(rate, homing, 0);
12627 clk2=48;
12628 ++misc;
12629 }
12630
12631 if(clk2==0)
12632 misc=0;
12633
12634 break;
12635 }
12636
12637 return enemy::animate(index);
12638 }
12639
12640 void eNPC::draw(BITMAP *dest)
12641 {
12642 update_enemy_frame();
12643 enemy::draw(dest);
12644 }
12645
12646 int32_t eNPC::takehit(weapon*)
12647 {
12648 return 0;
12649 }
12650
12651 eSpinTile::eSpinTile(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12652 {
12653 if(clk>0) // clk>0 when created by a Spinning Tile combo
12654 {
12655 o_tile=clk;
12656 cs=id>>12;
12657 }
12658
12659 id=id&0xFFF;
12660 clk=0;
12661 step=0;
12662 mainguy=false;
12663 SIZEflags = d->SIZEflags;
12664 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12665 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12666 // al_trace("Enemy txsz:%i\n", txsz);
12667 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12668 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
12669 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
12670 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
12671 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12672 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12673 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
12674 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
12675 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12676 {
12677 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12678 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12679 }
12680
12681 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
12682 }
12683
12684 void eSpinTile::facehero()
12685 {
12686 if(Hero.x-x==0)
12687 {
12688 if (Hero.y + 8 < y)
12689 dir = up;
12690 else
12691 dir = down;
12692 }
12693 else
12694 {
12695 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12696 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
12697
12698 if((ddir <= -5.0*PI/8.0) && (ddir > -7.0*PI/8.0))
12699 {
12700 dir=l_down;
12701 }
12702 else if ((ddir <= -3.0*PI / 8.0) && (ddir > -5.0*PI / 8.0))
12703 {
12704 dir=down;
12705 }
12706 else if ((ddir <= -1.0*PI / 8.0) && (ddir > -3.0*PI / 8.0))
12707 {
12708 dir=r_down;
12709 }
12710 else if ((ddir <= 1.0*PI / 8.0) && (ddir > -1.0*PI / 8.0))
12711 {
12712 dir=right;
12713 }
12714 else if ((ddir <= 3.0*PI / 8.0) && (ddir > 1.0*PI / 8.0))
12715 {
12716 dir=r_up;
12717 }
12718 else if ((ddir <= 5.0*PI / 8.0) && (ddir > 3.0*PI / 8.0))
12719 {
12720 dir=up;
12721 }
12722 else if ((ddir <= 7.0*PI / 8.0) && (ddir > 5.0*PI / 8.0))
12723 {
12724 dir=l_up;
12725 }
12726 else
12727 {
12728 dir=left;
12729 }
12730 }
12731 }
12732
12733
12734 bool eSpinTile::animate(int32_t index)
12735 {
12736 if(switch_hooked) return enemy::animate(index);
12737 if(fallclk||drownclk) return enemy::animate(index);
12738 if(dying)
12739 {
12740 return Dead(index);
12741 }
12742
12743 if(clk==0)
12744 {
12745 removearmos(x,y,ffcactivated);
12746 }
12747
12748 ++misc;
12749
12750 if(misc==96)
12751 {
12752 facehero();
12753 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12754 double ddir=atan2_MSVC2022_FIX(double((Hero.y)-y),double(Hero.x-x));
12755 angular=true;
12756 angle=ddir;
12757 step=zslongToFix(dstep*100);
12758 }
12759
12760 if(y>186 || y<=-16 || x>272 || x<=-16)
12761 kickbucket();
12762
12763 sprite::move(step);
12764 return enemy::animate(index);
12765 }
12766
12767 void eSpinTile::draw(BITMAP *dest)
12768 {
12769 update_enemy_frame();
12770 y-=(misc>>4);
12771 yofs+=2;
12772 enemy::draw(dest);
12773 yofs-=2;
12774 y+=(misc>>4);
12775 }
12776
12777 void eSpinTile::drawshadow(BITMAP *dest, bool translucent)
12778 {
12779 flip = 0;
12780 shadowtile = wpnsbuf[spr_shadow].tile+(clk%4);
12781 yofs+=4;
12782 if(!shadow_overpit(this))
12783 enemy::drawshadow(dest, translucent);
12784 yofs-=4;
12785 }
12786
12787 30 eZora::eZora(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,0)
12788 30 {
12789 //these are here to bypass compiler warnings about unused arguments
12790 10 Clk=Clk;
12791 10 mainguy=false;
12792
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
12793 /*if((x>-17 && x<0) && iswaterex(tmpscr->data[(((int32_t)y&0xF0)+((int32_t)x>>4))]))
12794 {
12795 clk=1;
12796 }*/
12797 //nets+880;
12798 10 SIZEflags = d->SIZEflags;
12799
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
10 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12800 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12801 // al_trace("Enemy txsz:%i\n", txsz);
12802
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
10 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12803
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
12804
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
12805
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
12806
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12807
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12808 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
12809
1/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
12810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12811 {
12812 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12813 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12814 }
12815
12816
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
12817 20 }
12818
12819 3006 void eZora::facehero()
12820 {
12821
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2977 times.
3006 if(Hero.x-x==0)
12822 {
12823 29 dir=(Hero.y+8<y)?up:down;
12824 29 }
12825 else
12826 {
12827 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12828 2977 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
12829
12830
3/4
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 2869 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
2977 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
12831 {
12832 108 dir=l_down;
12833 108 }
12834
3/4
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 2730 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 139 times.
2869 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
12835 {
12836 139 dir=down;
12837 139 }
12838
3/4
✓ Branch 0 taken 885 times.
✓ Branch 1 taken 1845 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 885 times.
2730 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
12839 {
12840 885 dir=r_down;
12841 885 }
12842
3/4
✓ Branch 0 taken 1130 times.
✓ Branch 1 taken 715 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1130 times.
1845 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
12843 {
12844 1130 dir=right;
12845 1130 }
12846
3/4
✓ Branch 0 taken 545 times.
✓ Branch 1 taken 170 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 545 times.
715 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
12847 {
12848 545 dir=r_up;
12849 545 }
12850
3/4
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 101 times.
170 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
12851 {
12852 101 dir=up;
12853 101 }
12854
2/4
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69 times.
✗ Branch 3 not taken.
69 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
12855 {
12856 69 dir=l_up;
12857 69 }
12858 else
12859 {
12860 dir=left;
12861 }
12862 }
12863 3006 }
12864
12865 4080 bool eZora::animate(int32_t index)
12866 {
12867
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4080 times.
4080 if(switch_hooked) return enemy::animate(index);
12868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4080 times.
4080 if(dying)
12869 return Dead(index);
12870
12871
2/2
✓ Branch 0 taken 4055 times.
✓ Branch 1 taken 25 times.
4080 if(clk==0)
12872 {
12873 25 removearmos(x,y,ffcactivated);
12874 25 }
12875
12876
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4080 times.
4080 if(watch)
12877 {
12878 ++clock_zoras[id];
12879 return true;
12880 }
12881
12882
2/2
✓ Branch 0 taken 1074 times.
✓ Branch 1 taken 3006 times.
4080 if(get_bit(quest_rules,qr_NEWENEMYTILES))
12883 {
12884 3006 facehero();
12885 3006 }
12886
12887
6/6
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 3973 times.
✓ Branch 4 taken 25 times.
✓ Branch 5 taken 15 times.
4080 switch(clk)
12888 {
12889 case 0: // reposition him
12890 {
12891 25 int32_t t=0;
12892 25 int32_t pos2=zc_oldrand()%160 + 16;
12893 25 bool placed=false;
12894
12895
4/4
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 88 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 25 times.
113 while(!placed && t<160)
12896 {
12897 38 int32_t watertype = iswaterex(tmpscr->data[pos2], currmap, currscr, -1, ((pos2)%16*16), ((pos2)&0xF0), false, true, true, (bool)(editorflags & ENEMY_FLAG7));
12898
4/6
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 25 times.
63 if(watertype && ((editorflags & ENEMY_FLAG6) ||
12899
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 ((combobuf[watertype].usrflags&cflag1) && (editorflags & ENEMY_FLAG5))
12900
3/4
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 25 times.
26 || (!(combobuf[watertype].usrflags&cflag1) && !(editorflags & ENEMY_FLAG5))) && (pos2&15)>0 && (pos2&15)<15)
12901 {
12902 25 x=(pos2&15)<<4;
12903 25 y=pos2&0xF0;
12904
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (!(editorflags & ENEMY_FLAG8)) hp=guysbuf[id&0xFFF].hp; // refill life each time, unless the flag is checked.
12905 25 hxofs=1000; // avoid hit detection
12906 25 stunclk=0;
12907 25 placed=true;
12908 25 }
12909
12910 88 pos2+=19;
12911
12912
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 11 times.
88 if(pos2>=176)
12913 11 pos2-=160;
12914
12915 88 ++t;
12916 }
12917
12918
2/4
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
25 if(!placed || whistleclk>=88) // can't place him, he's gone
12919 return true;
12920
12921 }
12922 25 break;
12923
12924 case 35:
12925
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 7 times.
24 if(!get_bit(quest_rules,qr_NEWENEMYTILES))
12926 {
12927 7 dir=(Hero.y+8<y)?up:down;
12928 7 }
12929
12930 24 hxofs=0;
12931 24 break;
12932
12933 case 35+19:
12934 23 addEwpn(x,y,z,wpn,2,wdp,dir,getUID(), 0, fakez);
12935 23 sfx(wpnsfx(wpn),pan(int32_t(x)));
12936 23 break;
12937
12938 case 35+66:
12939 20 hxofs=1000;
12940 20 break;
12941
12942 case 198:
12943 15 clk=-1;
12944 15 break;
12945 }
12946
12947 4080 return enemy::animate(index);
12948 4080 }
12949
12950 4080 void eZora::draw(BITMAP *dest)
12951 {
12952
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 4005 times.
4080 if(clk<3)
12953 75 return;
12954
12955 4005 update_enemy_frame();
12956 4005 enemy::draw(dest);
12957 4080 }
12958
12959 bool eZora::isSubmerged() const
12960 {
12961 return ( clk < 3 );
12962 }
12963
12964
4/8
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 221 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 221 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 221 times.
✗ Branch 7 not taken.
884 eStalfos::eStalfos(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12965 663 {
12966 221 multishot= timer = fired = dashing = 0;
12967 221 hashero = false;
12968 221 dummy_bool[0]=false;
12969 221 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
12970
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
221 if(dmisc9==e9tARMOS && zc_oldrand()&1)
12971 {
12972 step=zslongToFix(dmisc10*100);
12973
12974 if(anim==aARMOS4) o_tile+=20;
12975 }
12976
12977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
221 if(flags & guy_fadeflicker)
12978 {
12979 clk=0;
12980 superman = 1;
12981 fading=fade_flicker;
12982 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
12983 dir=down;
12984
12985 if(!canmove(down,(zfix)8,spw_none,false))
12986 clk3=int32_t(13.0/step);
12987 }
12988
1/2
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
221 else if(flags & guy_fadeinstant)
12989 {
12990 clk=0;
12991 }
12992
12993
1/2
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
221 shadowdistance = 0;
12994 221 clk4 = clk5 = 0;
12995 //nets+2380;
12996 221 SIZEflags = d->SIZEflags;
12997
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
221 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12998 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12999 // al_trace("Enemy txsz:%i\n", txsz);
13000
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
221 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
13001
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
221 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
13002
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
221 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
13003
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
221 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
13004
1/2
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
221 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
13005
1/2
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
221 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
13006 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
13007
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
221 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
13008
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
221 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
13009 {
13010 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
13011 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
13012 }
13013
13014
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 221 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
221 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
13015 442 }
13016
13017 83022 bool eStalfos::animate(int32_t index)
13018 {
13019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83022 times.
83022 if(switch_hooked) return enemy::animate(index);
13020
2/4
✓ Branch 0 taken 83022 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 83022 times.
83022 if(fallclk||drownclk)
13021 {
13022 return enemy::animate(index);
13023 }
13024
2/2
✓ Branch 0 taken 2862 times.
✓ Branch 1 taken 80160 times.
83022 if(dying)
13025 {
13026
1/2
✓ Branch 0 taken 2862 times.
✗ Branch 1 not taken.
2862 if(hashero)
13027 {
13028 Hero.setEaten(0);
13029 hashero=false;
13030 }
13031
13032
1/14
✗ Branch 0 not taken.
✓ Branch 1 taken 2862 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2862 if(dmisc9==e9tROPE && dmisc2==e2tBOMBCHU && !fired && (hp<=0 && !immortal) && hp>-1000 && wpn>wEnemyWeapons)
13033 {
13034 hp=-1000;
13035 weapon *ew=new weapon(x,y,z, wpn, 0, dmisc4, dir,-1,getUID(),false);
13036 Ewpns.add(ew);
13037 ew->fakez = fakez;
13038
13039 if(wpn==ewSBomb || wpn==ewBomb)
13040 {
13041 ew->step=0;
13042 ew->id=wpn;
13043 ew->misc=50;
13044 ew->clk=48;
13045 }
13046
13047 fired=true;
13048 }
13049
5/6
✓ Branch 0 taken 1854 times.
✓ Branch 1 taken 1008 times.
✓ Branch 2 taken 1710 times.
✓ Branch 3 taken 144 times.
✓ Branch 4 taken 1710 times.
✗ Branch 5 not taken.
2862 else if(wpn && wpn!=ewBrang && dmisc2==e2tFIREOCTO) // Fire Octo
13050 {
13051 if(!dummy_bool[0])
13052 {
13053 int32_t wpn2 = wpn+dmisc3;
13054
13055 if(wpn2 <= wEnemyWeapons || wpn2 >= wMax)
13056 {
13057 wpn2=wpn;
13058 }
13059
13060 dummy_bool[0]=true;
13061 addEwpn(x,y,z,wpn2,0,dmisc4,up, getUID(), 0, fakez);
13062 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13063 addEwpn(x,y,z,wpn2,0,dmisc4,down, getUID(), 0, fakez);
13064 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13065 addEwpn(x,y,z,wpn2,0,dmisc4,left, getUID(), 0, fakez);
13066 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13067 addEwpn(x,y,z,wpn2,0,dmisc4,right, getUID(), 0, fakez);
13068 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13069 addEwpn(x,y,z,wpn2,0,dmisc4,l_up, getUID(), 0, fakez);
13070 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13071 addEwpn(x,y,z,wpn2,0,dmisc4,r_up, getUID(), 0, fakez);
13072 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13073 addEwpn(x,y,z,wpn2,0,dmisc4,l_down, getUID(), 0, fakez);
13074 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13075 addEwpn(x,y,z,wpn2,0,dmisc4,r_down, getUID(), 0, fakez);
13076 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13077 sfx(wpnsfx(wpn2),pan(int32_t(x)));
13078 }
13079 }
13080
13081 2862 KillWeapon();
13082 2862 return Dead(index);
13083 }
13084 //vire split
13085 //2.10 checked !fslide(), but nothing uses that now anyway. -Z
13086 //Perhaps the problem occurs when vires die because they have < 0 HP, in this check?
13087
8/14
✓ Branch 0 taken 159 times.
✓ Branch 1 taken 80001 times.
✓ Branch 2 taken 159 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 159 times.
✓ Branch 6 taken 618 times.
✓ Branch 7 taken 79542 times.
✓ Branch 8 taken 618 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 618 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
80160 else if(((hp<=0 && !immortal) && dmisc2==e2tSPLIT) || (dmisc2==e2tSPLITHIT && hp>0 && hp<guysbuf[id&0xFFF].hp && !slide() && (sclk&255)<=1)) //Split into enemies
13088 {
13089 stop_bgsfx(index);
13090 int32_t kids = guys.Count();
13091 int32_t id2=dmisc3;
13092 for(int32_t i=0; i < dmisc4; i++)
13093 {
13094 // if (addenemy(x,y,id2+(guysbuf[id2].family==eeKEESE ? 0 : ((i+1)<<12)),-21-(i%4)))
13095 if(addenemy(x,y,id2+(guysbuf[id2].family==eeKEESE ? 0 : ((editorflags & ENEMY_FLAG5) ? 0 : (i<<12))),-21-(i%4)))
13096 ((enemy*)guys.spr(kids+i))->count_enemy = false;
13097 }
13098
13099 if(itemguy) // Hand down the carried item
13100 {
13101 guycarryingitem = guys.Count()-1;
13102 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
13103 itemguy = false;
13104 }
13105
13106 if(hashero)
13107 {
13108 Hero.setEaten(0);
13109 hashero=false;
13110 }
13111
13112 if(deadsfx > 0 && dmisc2==e2tSPLIT)
13113 sfx(deadsfx,pan(int32_t(x)));
13114
13115 return true;
13116 }
13117 /*
13118 else if((dmisc2==e2tSPLITHIT && (hp<=0 && !immortal) &&!slide())) //Possible vires fix; or could cause goodness knows what. -Z
13119 {
13120 stop_bgsfx(index);
13121 int32_t kids = guys.Count();
13122 int32_t id2=dmisc3;
13123
13124 for(int32_t i=0; i < dmisc4; i++)
13125 {
13126 // if (addenemy(x,y,id2+(guysbuf[id2].family==eeKEESE ? 0 : ((i+1)<<12)),-21-(i%4)))
13127 if(addenemy(x,y,id2+(guysbuf[id2].family==eeKEESE ? 0 : (i<<12)),-21-(i%4)))
13128 ((enemy*)guys.spr(kids+i))->count_enemy = false;
13129 }
13130
13131 if(itemguy) // Hand down the carried item
13132 {
13133 guycarryingitem = guys.Count()-1;
13134 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
13135 itemguy = false;
13136 }
13137
13138 if(hashero)
13139 {
13140 Hero.setEaten(0);
13141 hashero=false;
13142 }
13143
13144 return true;
13145 }
13146 */
13147
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 80150 times.
80160 if(fading)
13148 {
13149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(++clk4 > 60)
13150 {
13151 clk4=0;
13152 superman=0;
13153 fading=0;
13154
13155 if(flags2&cmbflag_armos && z==0 && fakez == 0)
13156 {
13157 //if a custom size (not 16px by 16px)
13158
13159 //if a custom size (not 16px by 16px)
13160 if (ffcactivated)
13161 removearmosffc(ffcactivated-1);
13162 else
13163 {
13164 if (txsz > 1 || tysz > 1 || (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) || (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) )//remove more than one combo based on enemy size
13165 {
13166 //zprint("spawn big enemy from armos\n");
13167 //if removing a block, then adjust y by -1 as the enemy spawns at y+1
13168 for(int32_t dx = 0; dx < tysz; dx ++)
13169 {
13170 for(int32_t dy = 0; dy < tysz; dy++)
13171 {
13172 removearmos((int32_t)x+(dx*16),(int32_t)y+(dy*16)+1);
13173 did_armos = false;
13174 }
13175 removearmos((int32_t)x+(dx*16), (int32_t)y+((tysz-1)*16)+1);
13176 did_armos = false;
13177 }
13178 for(int32_t dy = 0; dy < tysz; dy ++)
13179 {
13180 removearmos((int32_t)x+((txsz-1)*16), (int32_t)y+(dy*16)+1);
13181 did_armos = false;
13182 }
13183 removearmos((int32_t)x+((txsz-1)*16), (int32_t)y+((tysz-1)*16)+1);
13184 }
13185 else removearmos(x,y);
13186 }
13187 /*
13188 if (txsz > 1 || tysz > 1 || (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) || (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) )//remove more than one combo based on enemy size
13189 {
13190 //if removing a block, then adjust y by -1 as the enemy spawns at y+1
13191 for(int32_t dx = 0; dx < hxsz; dx += 16)
13192 {
13193 for(int32_t dy = 0; dy < hysz; dy += 16)
13194 {
13195 removearmos((int32_t)x+dx+hxofs,(int32_t)y+dy+hyofs+1,ffcactivated);
13196 did_armos = false;
13197 }
13198 removearmos((int32_t)x+dx+hxofs, (int32_t)y+hyofs+(hysz-1)-1,ffcactivated);
13199 did_armos = false;
13200 }
13201 for(int32_t dy = 0; dy < hysz; dy += 16)
13202 {
13203 removearmos((int32_t)x+hxofs+(hxsz-1), (int32_t)y+dy+hyofs-1,ffcactivated);
13204 did_armos = false;
13205 }
13206 removearmos((int32_t)x+hxofs+(hxsz-1), (int32_t)y+hyofs+(hysz-1)-1,ffcactivated);
13207 }
13208 else removearmos(x,y,ffcactivated);
13209 */
13210
13211 }
13212
13213 clk2=0;
13214
13215 newdir();
13216 }
13217 10 else return enemy::animate(index);
13218 }
13219
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 80150 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
80150 else if(flags2&cmbflag_armos && z==0 && fakez == 0 && clk==0)
13220 removearmos(x,y,ffcactivated);
13221
13222
13223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80150 times.
80150 if(hashero)
13224 {
13225 Hero.setX(x);
13226 Hero.setY(y);
13227 ++clk2;
13228
13229 if(clk2==(dmisc8==0 ? 95 : dmisc8))
13230 {
13231 switch(dmisc7)
13232 {
13233 case e7tEATITEMS:
13234 {
13235 for(int32_t i=0; i<MAXITEMS; i++)
13236 {
13237 if(itemsbuf[i].flags&ITEM_EDIBLE)
13238 game->set_item(i, false);
13239 }
13240
13241 break;
13242 }
13243
13244 case e7tEATMAGIC:
13245 game->change_dmagic(-1*game->get_magicdrainrate());
13246 break;
13247
13248 case e7tEATRUPEES:
13249 game->change_drupy(-1);
13250 break;
13251 }
13252
13253 clk2=0;
13254 }
13255
13256 if((clk&0x18)==8) // stop its animation on the middle frame
13257 --clk;
13258 }
13259
4/4
✓ Branch 0 taken 9746 times.
✓ Branch 1 taken 70404 times.
✓ Branch 2 taken 6464 times.
✓ Branch 3 taken 3282 times.
80150 else if(!(wpn==ewBrang && WeaponOut())) //WeaponOut uses misc
13260 {
13261 // Movement engine
13262
3/6
✓ Branch 0 taken 4906 times.
✓ Branch 1 taken 71962 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 71962 times.
✗ Branch 5 not taken.
76868 if(clk>=0) switch(id>>12)
13263 {
13264 case 0: // Normal movement
13265
13266 /*
13267 if((dmisc9==e9tLEEVER || dmisc9==e9tZ3LEEVER) && !slide()) //Leever
13268 {
13269 // Overloading clk4 (Tribble clock) here...
13270 step=17/100.0;
13271 if(clk4<32) misc=1;
13272 else if(clk4<48) misc=2;
13273 else if(clk4<300) { misc=3; step = dstep/100.0; }
13274 else if(clk4<316) misc=2;
13275 else if(clk4<412) misc=1;
13276 else if(clk4<540) { misc=0; step=0; }
13277 else clk4=0;
13278 if(clk4==48) clk=0;
13279 hxofs=(misc>=2)?0:1000;
13280 if (dmisc9==e9tLEEVER)
13281 variable_walk(rate, homing, 0);
13282 else
13283 variable_walk_8(rate, homing, 4, 0);
13284 break;
13285 }
13286 */
13287
2/4
✓ Branch 0 taken 71962 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 71962 times.
71962 if(dmisc9==e9tVIRE || dmisc9==e9tPOLSVOICE) //Vire
13288 {
13289 vire_hop();
13290 break;
13291 }
13292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71962 times.
71962 else if(dmisc9==e9tROPE) //Rope charge
13293 {
13294 if(!fired && dashing && !stunclk && !watch && !frozenclock)
13295 {
13296 if(dmisc2==e2tBOMBCHU && HeroInRange(16) && wpn+dmisc3 > wEnemyWeapons) //Bombchu
13297 {
13298
13299 if ( get_bit(quest_rules,qr_BOMBCHUSUPERBOMB) )
13300 {
13301 hp=-1000;
13302
13303 if(wpn+dmisc3 > wEnemyWeapons && wpn+dmisc3 < wMax)
13304 {
13305 weapon *ew=new weapon(x,y,z, wpn+dmisc3, 0, dmisc4, dir,-1,getUID());
13306 Ewpns.add(ew);
13307 ew->fakez = fakez;
13308
13309 if(wpn==ewSBomb || wpn==ewBomb)
13310 {
13311 ew->step=0;
13312 ew->id=wpn+dmisc3;
13313 ew->misc=50;
13314 ew->clk=48;
13315 }
13316
13317 fired=true;
13318 }
13319 else
13320 {
13321 weapon *ew=new weapon(x,y,z, wpn, 0, dmisc4, dir,-1,getUID());
13322 Ewpns.add(ew);
13323 ew->fakez = fakez;
13324
13325 if(wpn==ewSBomb || wpn==ewBomb)
13326 {
13327 ew->step=0;
13328 ew->id=wpn;
13329 ew->misc=50;
13330 ew->clk=48;
13331 }
13332
13333 fired=true;
13334 }
13335 }
13336
13337 else
13338 {
13339 hp=-1000;
13340
13341 int32_t wpn2;
13342 if(wpn+dmisc3 > wEnemyWeapons && wpn+dmisc3 < wMax)
13343 wpn2=wpn;
13344 else
13345 wpn2=wpn;
13346
13347 weapon *ew=new weapon(x,y,z, wpn2, 0, dmisc4, dir,-1,getUID());
13348 Ewpns.add(ew);
13349 ew->fakez = fakez;
13350
13351 if(wpn2==ewSBomb || wpn2==ewBomb)
13352 {
13353 ew->step=0;
13354 ew->id=wpn2;
13355 ew->misc=50;
13356 ew->clk=48;
13357 }
13358
13359 fired=true;
13360 }
13361 }
13362 }
13363
13364 charge_attack();
13365 break;
13366 }
13367 /*
13368 * Boomerang-throwers have a halt count of 1
13369 * Zols have a halt count of (zc_oldrand()&7)<<4
13370 * Gels have a halt count of ((zc_oldrand()&7)<<3)+2
13371 * Everything else has 48
13372 */
13373 else
13374 {
13375
2/2
✓ Branch 0 taken 6280 times.
✓ Branch 1 taken 65682 times.
71962 if(wpn==ewBrang) // Goriya
13376 {
13377 6280 halting_walk(rate,homing,0,hrate, 1);
13378 6280 }
13379
3/4
✓ Branch 0 taken 65682 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32949 times.
✓ Branch 3 taken 32733 times.
65682 else if(dmisc9==e9tNORMAL && wpn==0)
13380 {
13381
2/2
✓ Branch 0 taken 570 times.
✓ Branch 1 taken 32163 times.
32733 if(dmisc2==e2tSPLITHIT) // Zol
13382 {
13383 570 halting_walk(rate,homing,0,hrate,(zc_oldrand()&7)<<4);
13384 570 }
13385
4/4
✓ Branch 0 taken 9569 times.
✓ Branch 1 taken 22594 times.
✓ Branch 2 taken 4219 times.
✓ Branch 3 taken 5350 times.
32163 else if(frate<=8 && starting_hp==1) // Gel
13386 {
13387 5350 halting_walk(rate,homing,0,hrate,((zc_oldrand()&7)<<3)+2);
13388 5350 }
13389 else // Other
13390 {
13391 26813 halting_walk(rate,homing,0,hrate, 48);
13392 }
13393 32733 }
13394 else // Other
13395 {
13396 32949 halting_walk(rate,homing,0,hrate, 48);
13397 }
13398 }
13399
13400 //if not in midair, and Hero's swinging sword is nearby, jump.
13401 /*if (dmisc9==e9tZ3STALFOS && z==0 && (!(isSideViewGravity()) || !_walkflag(x,y+16,0))
13402 && Hero.getAttackClk()==5 && Hero.getAttack()==wSword && distance(x,y,Hero.getX(),Hero.getY())<32)
13403 {
13404 facehero(false);
13405 sclk=16+((dir^1)<<8);
13406 fall=-FEATHERJUMP;
13407 sfx(WAV_ZN1JUMP,pan(int32_t(x)));
13408 }*/
13409 71962 break;
13410
13411 // Following cases are for just after creation-by-splitting.
13412 case 1:
13413 if(misc==1)
13414 {
13415 dir=up;
13416 step=8;
13417 }
13418
13419 if(misc<=2)
13420 {
13421 move(step);
13422
13423 if(!canmove(dir,(zfix)0,0,false))
13424 dir=down;
13425 }
13426
13427 if(misc==3)
13428 {
13429 if(canmove(right,(zfix)16,0,false))
13430 x+=16;
13431 }
13432
13433 ++misc;
13434 break;
13435
13436 case 2:
13437 if(misc==1)
13438 {
13439 dir=down;
13440 step=8;
13441 }
13442
13443 if(misc<=2)
13444 {
13445 move(step);
13446 /*
13447 if(!canmove(dir,(zfix)0,0,false))
13448 dir=up;
13449 */
13450 }
13451
13452 if(misc==3)
13453 {
13454 if(canmove(left,(zfix)16,0,false))
13455 x-=16;
13456 }
13457
13458 ++misc;
13459 break;
13460
13461 default:
13462 if(misc==1)
13463 {
13464 dir=(zc_oldrand()%4);
13465 step=8;
13466 }
13467
13468 if(misc<=2)
13469 {
13470 move(step);
13471
13472 if(!canmove(dir,(zfix)0,0,false))
13473 dir=dir^1;
13474 }
13475
13476 if(misc==3)
13477 {
13478 if(dir >= left && canmove(dir,(zfix)16,0,false))
13479 x+=(dir==left ? -16 : 16);
13480 }
13481
13482 ++misc;
13483 break;
13484 71962 }
13485
13486
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 76868 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
76868 if(id>>12 && misc>=4) //recently spawned by a split enemy
13487 {
13488 id&=0xFFF;
13489 step = zslongToFix(dstep*100);
13490
13491 if(x<32) x=32;
13492
13493 if(x>208) x=208;
13494
13495 if(y<32) y=32;
13496
13497 if(y>128) y=128;
13498
13499 misc=3;
13500 }
13501 76868 }
13502 else
13503 {
13504 //sfx(wpnsfx(wpn),pan(int32_t(x)));
13505
1/2
✓ Branch 0 taken 3282 times.
✗ Branch 1 not taken.
3282 if(clk2>2) clk2--;
13506 }
13507
13508 // Fire Zol
13509
3/8
✓ Branch 0 taken 45988 times.
✓ Branch 1 taken 34162 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45988 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
80150 if(wpn && dmisc1==e1tEACHTILE && clk2==1 && !hclk)
13510 {
13511 addEwpn(x,y,z,wpn,0,wdp,dir, getUID(), 0, fakez);
13512 sfx(wpnsfx(wpn),pan(int32_t(x)));
13513
13514 int32_t i=Ewpns.Count()-1;
13515 weapon *ew = (weapon*)(Ewpns.spr(i));
13516
13517 if(wpn==ewFIRETRAIL && wpnsbuf[ewFIRETRAIL].frames>1)
13518 {
13519 ew->aframe=zc_oldrand()%wpnsbuf[ewFIRETRAIL].frames;
13520 if ( ew->do_animation ) ew->tile+=ew->aframe;
13521 }
13522 }
13523 // Goriya
13524
12/16
✓ Branch 0 taken 9746 times.
✓ Branch 1 taken 70404 times.
✓ Branch 2 taken 3344 times.
✓ Branch 3 taken 6402 times.
✓ Branch 4 taken 3225 times.
✓ Branch 5 taken 119 times.
✓ Branch 6 taken 3225 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3225 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3225 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3225 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3178 times.
✓ Branch 15 taken 47 times.
80150 else if(wpn==ewBrang && clk2==1 && sclk==0 && !stunclk && !frozenclock && !watch && wpn && !WeaponOut())
13525 {
13526 47 misc=index+100;
13527
7/14
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 47 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 47 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 47 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 47 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 47 times.
✗ Branch 13 not taken.
47 Ewpns.add(new weapon(x,y-fakez,z,wpn,misc,wdp,dir, -1,getUID(),false));
13528 47 ((weapon*)Ewpns.spr(Ewpns.Count()-1))->dummy_bool[0]=false;
13529
13530
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 if(dmisc1==2)
13531 {
13532 int32_t ndir=dir;
13533
13534 if(Hero.x-x==0)
13535 {
13536 ndir=(Hero.y+8<y)?up:down;
13537 }
13538 else //turn to face Hero
13539 {
13540 double _MSVC2022_tmp1, _MSVC2022_tmp2;
13541 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
13542
13543 if((ddir<=(((-2)*PI)/8))&&(ddir>(((-6)*PI)/8)))
13544 {
13545 ndir=down;
13546 }
13547 else if((ddir<=(((2)*PI)/8))&&(ddir>(((-2)*PI)/8)))
13548 {
13549 ndir=right;
13550 }
13551 else if((ddir<=(((6)*PI)/8))&&(ddir>(((2)*PI)/8)))
13552 {
13553 ndir=up;
13554 }
13555 else
13556 {
13557 ndir=left;
13558 }
13559 }
13560
13561 ((weapon*)Ewpns.spr(Ewpns.Count()-1))->dummy_bool[0]=true;
13562
13563 if(canmove(ndir,false))
13564 {
13565 dir=ndir;
13566 }
13567 }
13568 47 }
13569
13/16
✓ Branch 0 taken 79711 times.
✓ Branch 1 taken 392 times.
✓ Branch 2 taken 392 times.
✓ Branch 3 taken 79711 times.
✓ Branch 4 taken 228 times.
✓ Branch 5 taken 164 times.
✓ Branch 6 taken 228 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 227 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 186 times.
✓ Branch 11 taken 41 times.
✓ Branch 12 taken 186 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 186 times.
80103 else if((clk2==16 || dmisc1==e1tCONSTANT) && dmisc1!=e1tEACHTILE && wpn && wpn!=ewBrang && sclk==0 && !stunclk && !frozenclock && !watch)
13570
1/3
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
186 switch(dmisc1)
13571 {
13572 case e1tCONSTANT: //Deathnut
13573 {
13574 // Overloading clk5 (Like Like clock) to avoid making another clock just for this attack...
13575 if(clk5>64)
13576 {
13577 clk5=0;
13578 fired=false;
13579 }
13580
13581 clk5+=(zc_oldrand()&3);
13582
13583 if((clk5>24)&&(clk5<52))
13584 {
13585 if ( do_animation )tile+=20; //firing
13586
13587 if(!fired&&(clk5>=38))
13588 {
13589 Ewpns.add(new weapon(x,y,z, wpn, 0, wdp, dir, -1,getUID(),false));
13590 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
13591 sfx(wpnsfx(wpn),pan(int32_t(x)));
13592 fired=true;
13593 }
13594 }
13595
13596 break;
13597 }
13598
13599 case e1tFIREOCTO: //Fire Octo
13600 timer=zc_oldrand()%50+50;
13601 break;
13602
13603 default:
13604 186 FireWeapon();
13605 186 break;
13606 186 }
13607
13608 /* Fire again if:
13609 * - clk2 about to run out
13610 * - not already double-firing (dmisc1 is 1)
13611 * - not carrying Hero
13612 * - one in 0xF chance
13613 */
13614
8/10
✓ Branch 0 taken 3710 times.
✓ Branch 1 taken 76440 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 3658 times.
✓ Branch 4 taken 52 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 52 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 50 times.
80150 if(clk2==1 && (multishot < dmisc6) && dmisc1 != e1tEACHTILE && !hashero && !(zc_oldrand()&15))
13615 {
13616 #if 1
13617 2 newdir(rate, homing, grumble);
13618 #else
13619 dir^=2;
13620 #endif
13621 2 clk2=28;
13622 2 ++multishot;
13623 2 }
13624
13625
2/2
✓ Branch 0 taken 20724 times.
✓ Branch 1 taken 59426 times.
80150 if(clk2==0)
13626 {
13627 59426 multishot = 0;
13628 59426 }
13629
13630
1/2
✓ Branch 0 taken 80150 times.
✗ Branch 1 not taken.
80150 if(timer) //Fire Octo
13631 {
13632 clk2=15; //this keeps the octo in place until he's done firing
13633
13634 if(!(timer%4))
13635 {
13636 FireBreath(false);
13637 }
13638
13639 --timer;
13640 }
13641
13642
1/2
✓ Branch 0 taken 80150 times.
✗ Branch 1 not taken.
80150 if(dmisc2==e2tTRIBBLE)
13643 ++clk4;
13644
13645
2/10
✗ Branch 0 not taken.
✓ Branch 1 taken 80150 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 80150 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
80150 if(clk4==(dmisc5 ? dmisc5 : 256) && (dmisc2==e2tTRIBBLE) && dmisc3 && dmisc4)
13646 {
13647 int32_t kids = guys.Count();
13648 int32_t id2=dmisc3;
13649
13650 for(int32_t i=0; i<dmisc4; i++)
13651 {
13652 if(addenemy(x,y,id2,-24))
13653 {
13654 if(itemguy) // Hand down the carried item
13655 {
13656 guycarryingitem = guys.Count()-1;
13657 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
13658 itemguy = false;
13659 }
13660
13661 ((enemy*)guys.spr(kids+i))->count_enemy = false;
13662 }
13663 }
13664
13665 if(hashero)
13666 {
13667 Hero.setEaten(0);
13668 hashero=false;
13669 }
13670
13671 stop_bgsfx(index);
13672 return true;
13673 }
13674
13675 80150 return enemy::animate(index);
13676 83022 }
13677
13678 83036 void eStalfos::draw(BITMAP *dest)
13679 {
13680 /*if ((dmisc9==e9tLEEVER || dmisc9==e9tZ3LEEVER) && misc<=0) //Submerged
13681 {
13682 clk4--; //Kludge
13683 return;
13684 }*/
13685
13686 /*if ((dmisc9==e9tLEEVER || dmisc9==e9tZ3LEEVER) && misc>1)
13687 {
13688 cs = dcset;
13689 }*/
13690 83036 update_enemy_frame();
13691
13692
3/8
✓ Branch 0 taken 83036 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 83036 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 83036 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
83036 if(!fallclk&&!drownclk&&(dmisc2==e2tBOMBCHU)&&dashing)
13693 {
13694 if ( do_animation )tile+=20;
13695 }
13696
13697 83036 enemy::draw(dest);
13698 83036 }
13699
13700 28608 void eStalfos::drawshadow(BITMAP *dest, bool translucent)
13701 {
13702 28608 int32_t tempy=yofs;
13703
13704 /*
13705 if (clk6 && dir>=left && !get_bit(quest_rules,qr_ENEMIESZAXIS)) {
13706 flip = 0;
13707 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
13708 (clk/(frate/4)):((clk>=(frate>>1))?1:0);
13709 shadowtile = wpnsbuf[spr_shadow].tile+f2;
13710 yofs+=(((int32_t)y+17)&0xF0)-y;
13711 yofs+=8;
13712 }
13713 */
13714
2/4
✓ Branch 0 taken 28608 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28608 times.
✗ Branch 3 not taken.
28608 if((dmisc9 == e9tPOLSVOICE || dmisc9==e9tVIRE) && !get_bit(quest_rules,qr_ENEMIESZAXIS))
13715 {
13716 flip = 0;
13717 int32_t fdiv = frate/4;
13718 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
13719
13720 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
13721 efrate:((clk>=(frate>>1))?1:0);
13722 shadowtile = wpnsbuf[spr_shadow].tile;
13723
13724 if(get_bit(quest_rules,qr_NEWENEMYTILES))
13725 {
13726 shadowtile+=f2;
13727 }
13728 else
13729 {
13730 shadowtile+=f2?1:0;
13731 }
13732
13733 yofs+=shadowdistance;
13734 yofs+=8;
13735 }
13736
2/4
✓ Branch 0 taken 28608 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28608 times.
✗ Branch 3 not taken.
28608 if((dmisc9 == e9tPOLSVOICE || dmisc9==e9tVIRE) && !get_bit(quest_rules,qr_POLVIRE_NO_SHADOW))
13737 {
13738 flip = 0;
13739 int32_t fdiv = frate/4;
13740 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
13741
13742 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
13743 efrate:((clk>=(frate>>1))?1:0);
13744 shadowtile = wpnsbuf[spr_shadow].tile;
13745
13746 if(get_bit(quest_rules,qr_NEWENEMYTILES))
13747 {
13748 shadowtile+=f2;
13749 }
13750 else
13751 {
13752 shadowtile+=f2?1:0;
13753 }
13754 }
13755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28608 times.
28608 if(!shadow_overpit(this))
13756 28608 enemy::drawshadow(dest, translucent);
13757 28608 yofs=tempy;
13758 28608 }
13759
13760 431 int32_t eStalfos::takehit(weapon *w)
13761 {
13762 431 int32_t wpnId = w->id;
13763 431 int32_t wpnDir = w->dir;
13764
13765
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 431 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
431 if(wpnId==wHammer && shield && (flags & guy_bkshield)
13766 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
13767 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
13768 {
13769 shield = false;
13770 flags &= ~(inv_left|inv_right|inv_back|inv_front);
13771
13772 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
13773 o_tile=s_tile;
13774 }
13775
13776 431 int32_t ret = enemy::takehit(w);
13777
13778
3/4
✓ Branch 0 taken 161 times.
✓ Branch 1 taken 270 times.
✓ Branch 2 taken 161 times.
✗ Branch 3 not taken.
431 if(sclk && dmisc2==e2tSPLITHIT)
13779 sclk+=128; //Fuck these arbitrary values with no explanation. Fuck vires, too. -Z
13780
13781 431 return ret;
13782 }
13783
13784 void eStalfos::charge_attack()
13785 {
13786 if(slide())
13787 return;
13788
13789 if(clk<0 || dir<0 || stunclk || watch || ceiling || frozenclock )
13790 return;
13791
13792 if(clk3<=0)
13793 {
13794 fix_coords(true);
13795
13796 if(!dashing)
13797 {
13798 int32_t ldir = lined_up(7,false);
13799
13800 if(ldir!=-1 && canmove(ldir,false))
13801 {
13802 dir=ldir;
13803 dashing=true;
13804 step=zslongToFix(dstep*100)+1;
13805 }
13806 else newdir(4,0,0);
13807 }
13808
13809 if(!canmove(dir,false))
13810 {
13811 step=zslongToFix(dstep*100);
13812 newdir();
13813 dashing=false;
13814 }
13815
13816 zfix div = step;
13817
13818 if(div == 0)
13819 div = 1;
13820
13821 clk3=(int32_t)(16.0/div);
13822 return;
13823 }
13824
13825 move(step);
13826 --clk3;
13827 }
13828
13829 void eStalfos::vire_hop()
13830 {
13831 //if ( sclk > 0 ) return; //Don't hop during knockback.
13832
13833 // if(dmisc9!=e9tPOLSVOICE)
13834 // {
13835 // //if( slide() /*sclk!=0*/ && dmisc2==e2tSPLIT) //Vires with split on hit, only! -Z
13836 // if( sclk!=0 && dmisc2==e2tSPLIT) //Vires with split on hit, only! -Z
13837 // return; //the enemy should split if it is sliding!
13838 // //else sclk=0; //might need this here, too. -Z
13839 // }
13840 if(dmisc9!=e9tPOLSVOICE)
13841 {
13842 if(sclk!=0)
13843 {
13844 if (dmisc2==e2tSPLITHIT) return;
13845 //return;
13846 }
13847 }
13848 else sclk=0;
13849
13850 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
13851 return;
13852
13853 int32_t jump_width = (dmisc9==e9tPOLSVOICE) ? 2 : 1;
13854 int32_t jump_height = (dmisc9==e9tPOLSVOICE) ? 27 : 16;
13855
13856 y=floor_y;
13857
13858 if(clk3<=0)
13859 {
13860 fix_coords();
13861
13862 //z=0;
13863 //if we're not in the middle of a jump or if we can't complete the current jump in the current direction
13864 //if(clk2<=0 || !canmove(dir,(zfix)1,spw_floater,false) || (isSideViewGravity() && isOnSideviewPlatform()))
13865 if(clk2<=0 || !canmove(dir,(zfix)1,spw_floater,false) || (isSideViewGravity() && (isOnSideviewPlatform() || !(moveflags & FLAG_OBEYS_GRAV)))) //Vires in old quests
13866 newdir(rate,homing,dmisc9==e9tPOLSVOICE ? spw_floater : spw_none);
13867
13868 if(clk2<=0)
13869 {
13870 //z=0;
13871 if(!canmove(dir,(zfix)2,spw_none,false) || m_walkflag(x,y,spw_none, dir) || (zc_oldrand()&15)>=hrate)
13872 {
13873
13874 clk2=(wpn==ewBrang ? 1 : int32_t((16.0*jump_width)/step.getFloat()));
13875 /*if (dmisc9==e9tPOLSVOICE )
13876 {
13877 zprint2("polsvoice jump_width is: %d\n", jump_width);
13878 zprint2("polsvoice raw step is: %d\n", step);
13879 zprint2("polsvoice step.getInt() is: %d\n", step.getInt());
13880 zprint2("setting clk2 on polsvoice to: %d\n", clk2);
13881 }
13882 else
13883 {
13884 zprint2("vire jump_width is: %d\n", jump_width);
13885 zprint2("vire raw step is: %d\n", step);
13886 zprint2("vire step.getInt() is: %d\n", step.getInt());
13887 zprint2("setting clk2 on vire to: %d\n", clk2);
13888 }
13889 */
13890 }
13891 }
13892
13893 if(dmisc9!=e9tPOLSVOICE && dir>=left) //if we're moving left or right
13894 {
13895 clk2=int32_t((16.0*jump_width)/step.getFloat());
13896 }
13897
13898 clk3=int32_t(16.0/step.getFloat());
13899 }
13900
13901 --clk3;
13902
13903 if(dmisc9==e9tPOLSVOICE || clk2>0)
13904 move(step);
13905
13906 floor_y=y;
13907 clk2--;
13908
13909 //if we're in the middle of a jump
13910 if(clk2>0 && (dir>=left || dmisc9==e9tPOLSVOICE))
13911 {
13912 int32_t h = fixtoi(fixsin(itofix(clk2*128*step/(16*jump_width)))*jump_height);
13913
13914 if(get_bit(quest_rules,qr_ENEMIESZAXIS) && !(isSideViewGravity()))
13915 {
13916 if (moveflags & FLAG_USE_FAKE_Z) fakez=h;
13917 else z=h;
13918 }
13919 else
13920 {
13921 //y+=fixtoi(fixsin(itofix((clk2+1)*128*step/(16*jump_width)))*jump_height);
13922 //y-=h;
13923 y=floor_y-h;
13924 shadowdistance=h;
13925 }
13926 }
13927 else
13928 shadowdistance = 0;
13929 }
13930
13931 void eStalfos::eathero()
13932 {
13933 if(!hashero && Hero.getEaten()==0 && Hero.getAction() != hopping && Hero.getAction() != swimming)
13934 {
13935 hashero=true;
13936 y=floor_y;
13937 z=0;
13938
13939 if(Hero.isSwimming())
13940 {
13941 Hero.setX(x);
13942 Hero.setY(y);
13943 }
13944 else
13945 {
13946 x=Hero.getX();
13947 y=Hero.getY();
13948 }
13949
13950 clk2=0;
13951 }
13952 }
13953
13954 12971 bool eStalfos::WeaponOut()
13955 {
13956
2/2
✓ Branch 0 taken 14176 times.
✓ Branch 1 taken 6511 times.
20687 for(int32_t i=0; i<Ewpns.Count(); i++)
13957 {
13958
3/4
✓ Branch 0 taken 6460 times.
✓ Branch 1 taken 7716 times.
✓ Branch 2 taken 6460 times.
✗ Branch 3 not taken.
14176 if(((weapon*)Ewpns.spr(i))->parentid==getUID() && Ewpns.spr(i)->id==ewBrang)
13959 {
13960 6460 return true;
13961 }
13962
13963 /*if (bgsfx > 0 && guys.idCount(id) < 2) // count self
13964 stop_sfx(bgsfx);
13965 */
13966 7716 }
13967
13968 6511 return false;
13969 12971 }
13970
13971 2862 void eStalfos::KillWeapon()
13972 {
13973
2/2
✓ Branch 0 taken 2862 times.
✓ Branch 1 taken 811 times.
3673 for(int32_t i=0; i<Ewpns.Count(); i++)
13974 {
13975
4/4
✓ Branch 0 taken 773 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 772 times.
✓ Branch 3 taken 1 times.
811 if(((weapon*)Ewpns.spr(i))->type==misc && Ewpns.spr(i)->id==ewBrang)
13976 {
13977 //only kill this Goriya's boomerang -DD
13978
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(((weapon *)Ewpns.spr(i))->parentid == getUID())
13979 {
13980 1 Ewpns.del(i);
13981 1 }
13982 1 }
13983 811 }
13984
13985
4/4
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 2718 times.
✓ Branch 2 taken 111 times.
✓ Branch 3 taken 33 times.
2862 if(wpn==ewBrang && !Ewpns.idCount(ewBrang))
13986 {
13987 111 stop_sfx(WAV_BRANG);
13988 111 }
13989 2862 }
13990
13991 void eStalfos::break_shield()
13992 {
13993 if(!shield)
13994 return;
13995
13996 flags&=~(inv_front | inv_back | inv_left | inv_right);
13997 shield=false;
13998
13999 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
14000 o_tile=s_tile;
14001 }
14002
14003 264 eKeese::eKeese(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
14004 264 {
14005
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 dir=(zc_oldrand()&7)+8;
14006
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 step=0;
14007 88 movestatus=1;
14008
2/4
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 88 times.
88 if (dmisc1 != 1 && dmisc19 > 0)
14009 {
14010 step = dmisc19/100.0;
14011 movestatus = 1;
14012 }
14013
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 if (dmisc1 == 2) movestatus=2;
14014 88 c=0;
14015 88 SIZEflags = d->SIZEflags;
14016
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if ( !(SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) ) hxofs=2;
14017
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
14018
14019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if ( !(SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ) hxsz=12;
14020
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
88 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
14021
14022
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if ( !(SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) ) hyofs=4;
14023
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
14024
14025
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if ( !(SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ) hysz=8;
14026
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
88 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
14027
14028
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
88 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
14029 //al_trace("->txsz:%i\n", d->txsz); Verified that this is setting the value. -Z
14030 // al_trace("Enemy txsz:%i\n", txsz);
14031
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
88 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
14032
14033
14034
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
88 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
14035
14036
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
88 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
14037
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
14038 {
14039 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
14040 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
14041 }
14042
14043
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
88 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
14044 88 clk4=0;
14045 //nets;
14046 88 dummy_int[1]=0;
14047 176 }
14048
14049 24307 bool eKeese::animate(int32_t index)
14050 {
14051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24307 times.
24307 if(switch_hooked) return enemy::animate(index);
14052
2/4
✓ Branch 0 taken 24307 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24307 times.
24307 if(fallclk||drownclk) return enemy::animate(index);
14053
2/2
✓ Branch 0 taken 1247 times.
✓ Branch 1 taken 23060 times.
24307 if(dying)
14054 1247 return Dead(index);
14055
14056
2/2
✓ Branch 0 taken 22929 times.
✓ Branch 1 taken 131 times.
23060 if(clk==0)
14057 {
14058 131 removearmos(x,y,ffcactivated);
14059 131 }
14060
14061
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23060 times.
23060 if(dmisc1 == 1) //Walk style. 0 is keese, 1 is bat.
14062 {
14063 floater_walk(rate,hrate,dstep/100,(zfix)0,10,dmisc16,dmisc17);
14064 }
14065 else
14066 {
14067
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23060 times.
23060 if (dmisc18) floater_walk(rate,hrate,dstep/100,dmisc18/100.0,-1,dmisc16,dmisc17);
14068 23060 else floater_walk(rate,hrate,dstep/100,dstep/1000,10,dmisc16,dmisc17);
14069 }
14070
14071
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23060 times.
23060 if(dmisc2 == e2tKEESETRIB)
14072 {
14073 if(++clk4==(dmisc20>0?dmisc20:256))
14074 {
14075 if(!m_walkflag(x,y,0, dir))
14076 {
14077 int32_t kids = guys.Count();
14078 bool success = false;
14079 int32_t id2=dmisc3;
14080 success = 0 != addenemy((zfix)x,(zfix)y,id2,-24);
14081
14082 if(success)
14083 {
14084 if(itemguy) // Hand down the carried item
14085 {
14086 guycarryingitem = guys.Count()-1;
14087 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
14088 itemguy = false;
14089 }
14090
14091 ((enemy*)guys.spr(kids))->count_enemy = count_enemy;
14092 }
14093
14094 stop_bgsfx(index);
14095 return true;
14096 }
14097 else
14098 {
14099 clk4=0;
14100 }
14101 }
14102 }
14103 // Keese Tribbles stay on the ground, so there's no problem when they transform.
14104
3/4
✓ Branch 0 taken 8834 times.
✓ Branch 1 taken 14226 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8834 times.
23060 else if(get_bit(quest_rules,qr_ENEMIESZAXIS) && !(isSideViewGravity()))
14105 {
14106
1/2
✓ Branch 0 taken 8834 times.
✗ Branch 1 not taken.
8834 if (get_bit(quest_rules,qr_OLD_KEESE_Z_AXIS))
14107 {
14108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8834 times.
8834 if (moveflags & FLAG_USE_FAKE_Z)
14109 {
14110 fakez=int32_t(step/zslongToFix(dstep*100));
14111 // Some variance in keese flight heights when away from Hero
14112 fakez+=int32_t(step*zc_max(zfix(0),(distance(x,y,HeroX(),HeroY())-128)/10));
14113
14114 }
14115 else
14116 {
14117 8834 z=int32_t(step/zslongToFix(dstep*100));
14118 // Some variance in keese flight heights when away from Hero
14119
2/2
✓ Branch 0 taken 8310 times.
✓ Branch 1 taken 524 times.
8834 z+=int32_t(step*zc_max(zfix(0),(distance(x,y,HeroX(),HeroY())-128)/10));
14120 }
14121 8834 }
14122 else
14123 {
14124 if (moveflags & FLAG_USE_FAKE_Z)
14125 {
14126 fakez=int32_t(step/zslongToFix(dstep*100));
14127 // Some variance in keese flight heights when away from Hero
14128 fakez+=int32_t(step*zc_max(zfix(0),(distance(x,y,HeroX(),HeroY())-40)/4));
14129
14130 }
14131 else
14132 {
14133 z=int32_t(step/zslongToFix(dstep*100));
14134 // Some variance in keese flight heights when away from Hero
14135 z+=int32_t(step*zc_max(zfix(0),(distance(x,y,HeroX(),HeroY())-40)/4));
14136 }
14137 }
14138 8834 }
14139
14140 23060 return enemy::animate(index);
14141 24307 }
14142
14143 4685 void eKeese::drawshadow(BITMAP *dest, bool translucent)
14144 {
14145 4685 int32_t tempy=yofs;
14146 4685 flip = 0;
14147 4685 shadowtile = wpnsbuf[spr_shadow].tile+posframe;
14148
14149
2/2
✓ Branch 0 taken 2135 times.
✓ Branch 1 taken 2550 times.
4685 yofs+=zc_min(int32_t(step/zslongToFix(dstep*10)), 8);
14150
1/2
✓ Branch 0 taken 4685 times.
✗ Branch 1 not taken.
4685 if(!get_bit(quest_rules,qr_ENEMIESZAXIS))
14151 {
14152 yofs+=int32_t(step/zslongToFix(dstep*10));
14153 }
14154
14155
4/6
✓ Branch 0 taken 4685 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4685 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4558 times.
✓ Branch 5 taken 127 times.
4685 if(!shadow_overpit(this) && (!get_bit(quest_rules,qr_ENEMIESZAXIS) || step > 0))
14156 4558 enemy::drawshadow(dest, translucent);
14157 4685 yofs=tempy;
14158 4685 }
14159
14160 55991 void eKeese::draw(BITMAP *dest)
14161 {
14162 55991 update_enemy_frame();
14163 55991 enemy::draw(dest);
14164 55991 }
14165
14166 void eWizzrobe::submerge(bool set)
14167 {
14168 if(get_bit(quest_rules,qr_OLD_WIZZROBE_SUBMERGING))
14169 {
14170 hxofs = set?1000:0;
14171 return;
14172 }
14173 if(submerged == set) return;
14174 submerged = set;
14175 if(set)
14176 hxofs+=1000;
14177 else hxofs -= 1000;
14178 }
14179 eWizzrobe::eWizzrobe(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
14180 {
14181 hxofs = 0;
14182 submerged = false;
14183 switch(dmisc1)
14184 {
14185 case 0:
14186 submerge(true);
14187 fading=fade_invisible;
14188 // Set clk to just before the 'reappear' threshold
14189 clk=zc_min(clk+(146+zc_max(0,dmisc5))+14,(146+zc_max(0,dmisc5))-1);
14190 break;
14191
14192 default:
14193 dir=(loadside==right)?right:left;
14194 misc=-3;
14195 break;
14196 }
14197
14198 //netst+2880;
14199 charging=false;
14200 firing=false;
14201 fclk=0;
14202 if(!dmisc1) frate=1200+146; //1200 = 20 seconds
14203 SIZEflags = d->SIZEflags;
14204 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
14205 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
14206 // al_trace("Enemy txsz:%i\n", txsz);
14207 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
14208 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
14209 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
14210 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
14211 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 )
14212 {
14213 hxofs = (submerged?hxofs:0)+d->hxofs;
14214 }
14215 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
14216 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
14217 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
14218 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
14219 {
14220 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
14221 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
14222 }
14223
14224 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
14225 }
14226
14227 bool eWizzrobe::animate(int32_t index)
14228 {
14229 if(switch_hooked) return enemy::animate(index);
14230 if(fallclk||drownclk) return enemy::animate(index);
14231 if(dying)
14232 {
14233 return Dead(index);
14234 }
14235
14236 if(clk==0)
14237 {
14238 removearmos(x,y,ffcactivated);
14239 }
14240
14241 if(dmisc1) // Floating
14242 {
14243 wizzrobe_attack();
14244 }
14245 else // Teleporting
14246 {
14247 if(watch || (!get_bit(quest_rules, qr_WIZZROBES_DONT_OBEY_STUN) && stunclk))
14248 {
14249 fading=0;
14250 submerge(false);
14251 solid_update(false);
14252 }
14253 else switch(clk)
14254 {
14255 case 0:
14256 if(!dmisc2)
14257 {
14258 // Wizzrobe Misc4 controls whether wizzrobes can teleport on top of solid combos,
14259 // but should not appear on dungeon walls.
14260 if ( FFCore.getQuestHeaderInfo(vZelda) <= 0x190 ) place_on_axis(true, false); //1.84, and probably 1.90 wizzrobes should NEVER appear in dungeon walls.-Z (1.84 confirmed, 15th January, 2019 by Chris Miller).
14261 else if (editorflags&ENEMY_FLAG5)
14262 {
14263 //2.10 Windrobe
14264 //randomise location and face Hero
14265 int32_t t=0;
14266 bool placed=false;
14267
14268 while(!placed && t<160)
14269 {
14270 if(isdungeon())
14271 {
14272 x=((zc_oldrand()%12)+2)*16;
14273 y=((zc_oldrand()%7)+2)*16;
14274 }
14275 else
14276 {
14277 x=((zc_oldrand()%14)+1)*16;
14278 y=((zc_oldrand()%9)+1)*16;
14279 }
14280
14281 if(!m_walkflag(x,y,spw_door, dir)&&((abs(x-Hero.getX())>=32)||(abs(y-Hero.getY())>=32)))
14282 {
14283 placed=true;
14284 }
14285
14286 ++t;
14287 }
14288
14289 if(abs(x-Hero.getX())<abs(y-Hero.getY()))
14290 {
14291 if(y<Hero.getY())
14292 {
14293 dir=down;
14294 }
14295 else
14296 {
14297 dir=up;
14298 }
14299 }
14300 else
14301 {
14302 if(x<Hero.getX())
14303 {
14304 dir=right;
14305 }
14306 else
14307 {
14308 dir=left;
14309 }
14310 }
14311
14312 if(!placed) // can't place him, he's gone
14313 return true;
14314
14315
14316 //wizzrobe_attack(); //Complaint about 2.10 Windrobes not behaving as they did in 2.10. Let's try it this way. -Z
14317 //wizzrobe_attack_for_real(); //doing this makes them fire twice. The rest is correct.
14318 }
14319 else place_on_axis(true, dmisc4!=0);
14320 }
14321 else
14322 {
14323 int32_t t=0;
14324 bool placed=false;
14325
14326 while(!placed && t<160)
14327 {
14328 if(isdungeon())
14329 {
14330 x=((zc_oldrand()%12)+2)*16;
14331 y=((zc_oldrand()%7)+2)*16;
14332 }
14333 else
14334 {
14335 x=((zc_oldrand()%14)+1)*16;
14336 y=((zc_oldrand()%9)+1)*16;
14337 }
14338
14339 if(!m_walkflag(x,y,spw_door, dir)&&((abs(x-Hero.getX())>=32)||(abs(y-Hero.getY())>=32)))
14340 {
14341 placed=true;
14342 }
14343
14344 ++t;
14345 }
14346
14347 if(abs(x-Hero.getX())<abs(y-Hero.getY()))
14348 {
14349 if(y<Hero.getY())
14350 {
14351 dir=down;
14352 }
14353 else
14354 {
14355 dir=up;
14356 }
14357 }
14358 else
14359 {
14360 if(x<Hero.getX())
14361 {
14362 dir=right;
14363 }
14364 else
14365 {
14366 dir=left;
14367 }
14368 }
14369
14370 if(!placed) // can't place him, he's gone
14371 return true;
14372 }
14373
14374 fading=fade_flicker;
14375 submerge(false);
14376 solid_update(false);
14377 break;
14378
14379 case 64:
14380 fading=0;
14381 charging=true;
14382 break;
14383
14384 case 73:
14385 charging=false;
14386 firing=40;
14387 break;
14388
14389 case 83:
14390 wizzrobe_attack_for_real();
14391 break;
14392
14393 case 119:
14394 firing=false;
14395 charging=true;
14396 break;
14397
14398 case 128:
14399 fading=fade_flicker;
14400 charging=false;
14401 break;
14402
14403 case 146:
14404 fading=fade_invisible;
14405 submerge(true);
14406 solid_update(false);
14407
14408 [[fallthrough]];
14409 default:
14410 if(clk>=(146+zc_max(0,dmisc5)))
14411 clk=-1;
14412
14413 break;
14414 }
14415 }
14416
14417 return enemy::animate(index);
14418 }
14419
14420 void eWizzrobe::wizzrobe_attack_for_real()
14421 {
14422 if(wpn==0) // Edited enemies
14423 return;
14424
14425 if(dmisc2 == 0) //normal weapon
14426 {
14427 addEwpn(x,y,z,wpn,0,wdp,dir,getUID(), 0, fakez);
14428 sfx(WAV_WAND,pan(int32_t(x)));
14429 }
14430 else if(dmisc2 == 1) // ring of fire
14431 {
14432 addEwpn(x,y,z,wpn,0,wdp,up,getUID(), 0, fakez);
14433 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14434 addEwpn(x,y,z,wpn,0,wdp,down,getUID(), 0, fakez);
14435 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14436 addEwpn(x,y,z,wpn,0,wdp,left,getUID(), 0, fakez);
14437 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14438 addEwpn(x,y,z,wpn,0,wdp,right,getUID(), 0, fakez);
14439 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14440 addEwpn(x,y,z,wpn,0,wdp,l_up,getUID(), 0, fakez);
14441 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14442 addEwpn(x,y,z,wpn,0,wdp,r_up,getUID(), 0, fakez);
14443 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14444 addEwpn(x,y,z,wpn,0,wdp,l_down,getUID(), 0, fakez);
14445 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14446 addEwpn(x,y,z,wpn,0,wdp,r_down,getUID(), 0, fakez);
14447 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14448 sfx(WAV_FIRE,pan(int32_t(x)));
14449 if (get_bit(quest_rules, qr_8WAY_SHOT_SFX)) sfx(WAV_FIRE,pan(int32_t(x)));
14450 else
14451 {
14452 switch(wpn)
14453 {
14454 case ewFireball: sfx(40,pan(int32_t(x))); break;
14455
14456 case ewArrow: sfx(1,pan(int32_t(x))); break; //Ghost.zh has 0?
14457 case ewBrang: sfx(4,pan(int32_t(x))); break; //Ghost.zh has 0?
14458 case ewSword: sfx(20,pan(int32_t(x))); break; //Ghost.zh has 0?
14459 case ewRock: sfx(51,pan(int32_t(x))); break;
14460 case ewMagic: sfx(32,pan(int32_t(x))); break;
14461 case ewBomb: sfx(3,pan(int32_t(x))); break; //Ghost.zh has 0?
14462 case ewSBomb: sfx(3,pan(int32_t(x))); break; //Ghost.zh has 0?
14463 case ewLitBomb: sfx(21,pan(int32_t(x))); break; //Ghost.zh has 0?
14464 case ewLitSBomb: sfx(21,pan(int32_t(x))); break; //Ghost.zh has 0?
14465 case ewFireTrail: sfx(13,pan(int32_t(x))); break;
14466 case ewFlame: sfx(13,pan(int32_t(x))); break;
14467 case ewWind: sfx(32,pan(int32_t(x))); break;
14468 case ewFlame2: sfx(13,pan(int32_t(x))); break;
14469 case ewFlame2Trail: sfx(13,pan(int32_t(x))); break;
14470 case ewIce: sfx(44,pan(int32_t(x))); break;
14471 case ewFireball2: sfx(40,pan(int32_t(x))); break; //fireball (rising)
14472 default: sfx(WAV_FIRE,pan(int32_t(x))); break;
14473
14474 }
14475 }
14476 }
14477 else if(dmisc2==2) // summons specific enemy
14478 {
14479 int32_t bc=0;
14480
14481 for(int32_t gc=0; gc<guys.Count(); gc++)
14482 {
14483 if((((enemy*)guys.spr(gc))->id) == dmisc3)
14484 {
14485 ++bc;
14486 }
14487 }
14488
14489 if(bc<=40)
14490 {
14491 int32_t kids = guys.Count();
14492 int32_t bats=(zc_oldrand()%3)+1;
14493
14494 for(int32_t i=0; i<bats; i++)
14495 {
14496 // Summon bats (or anything)
14497 if(addchild(x,y,dmisc3,-10, this->script_UID))
14498 ((enemy*)guys.spr(kids+i))->count_enemy = false;
14499 }
14500
14501 sfx(WAV_FIRE,pan(int32_t(x)));
14502 }
14503 }
14504 else if(dmisc2==3) //summon from layer
14505 {
14506 if(count_layer_enemies()==0)
14507 {
14508 return;
14509 }
14510
14511 int32_t kids = guys.Count();
14512
14513 if(kids<200)
14514 {
14515 int32_t newguys=(zc_oldrand()%3)+1;
14516 bool summoned=false;
14517
14518 for(int32_t i=0; i<newguys; i++)
14519 {
14520 int32_t id2=vbound(random_layer_enemy(),eSTART,eMAXGUYS-1);
14521 int32_t x2=0;
14522 int32_t y2=0;
14523
14524 for(int32_t k=0; k<20; ++k)
14525 {
14526 x2=16*((zc_oldrand()%12)+2);
14527 y2=16*((zc_oldrand()%7)+2);
14528
14529 if(!m_walkflag(x2,y2,0, dir) && (abs(x2-Hero.getX())>=32 || abs(y2-Hero.getY())>=32))
14530 {
14531 if(addchild(x2,y2,get_bit(quest_rules,qr_ENEMIESZAXIS) ? 64 : 0,id2,-10, this->script_UID))
14532 {
14533 ((enemy*)guys.spr(kids+i))->count_enemy = false;
14534 if (get_bit(quest_rules,qr_ENEMIESZAXIS) && (((enemy*)guys.spr(kids+i))->moveflags & FLAG_USE_FAKE_Z))
14535 {
14536 ((enemy*)guys.spr(kids+i))->fakez = 64;
14537 ((enemy*)guys.spr(kids+i))->z = 0;
14538 }
14539 }
14540
14541 summoned=true;
14542 break;
14543 }
14544 }
14545 }
14546
14547 if(summoned)
14548 {
14549 sfx(get_bit(quest_rules,qr_MORESOUNDS) ? WAV_ZN1SUMMON : WAV_FIRE,pan(int32_t(x)));
14550 }
14551 }
14552 }
14553 }
14554
14555
14556 void eWizzrobe::wizzrobe_attack()
14557 {
14558 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
14559 return;
14560
14561 if(clk3<=0 || ((clk3&31)==0 && !canmove(dir,(zfix)1,spw_door,false) && !misc))
14562 {
14563 fix_coords();
14564
14565 switch(misc)
14566 {
14567 case 1: //walking
14568 if(!m_walkflag(x,y,spw_door, dir))
14569 misc=0;
14570 else
14571 {
14572 clk3=16;
14573
14574 if(!canmove(dir,(zfix)1,spw_wizzrobe,false))
14575 {
14576 wizzrobe_newdir(0);
14577 }
14578 }
14579
14580 break;
14581
14582 case 2: //phasing
14583 {
14584 int32_t jx=x;
14585 int32_t jy=y;
14586 int32_t jdir=-1;
14587
14588 switch(zc_oldrand()&7)
14589 {
14590 case 0:
14591 jx-=32;
14592 jy-=32;
14593 jdir=15;
14594 break;
14595
14596 case 1:
14597 jx+=32;
14598 jy-=32;
14599 jdir=9;
14600 break;
14601
14602 case 2:
14603 jx+=32;
14604 jy+=32;
14605 jdir=11;
14606 break;
14607
14608 case 3:
14609 jx-=32;
14610 jy+=32;
14611 jdir=13;
14612 break;
14613 }
14614
14615 if(jdir>0 && jx>=32 && jx<=208 && jy>=32 && jy<=128)
14616 {
14617 misc=3;
14618 clk3=32;
14619 dir=jdir;
14620 break;
14621 }
14622 }
14623 [[fallthrough]];
14624 case 3:
14625 dir&=3;
14626 misc=0;
14627 [[fallthrough]];
14628 case 0:
14629 wizzrobe_newdir(64);
14630 [[fallthrough]];
14631 default:
14632 if(!canmove(dir,(zfix)1,spw_door,false))
14633 {
14634 if(canmove(dir,(zfix)15,spw_wizzrobe,false))
14635 {
14636 misc=1;
14637 clk3=16;
14638 }
14639 else
14640 {
14641 wizzrobe_newdir(64);
14642 misc=0;
14643 clk3=32;
14644 }
14645 }
14646 else
14647 {
14648 clk3=32;
14649 }
14650
14651 break;
14652 }
14653
14654 if(misc<0)
14655 ++misc;
14656 }
14657
14658 --clk3;
14659
14660 switch(misc)
14661 {
14662 case 1:
14663 case 3:
14664 step=1;
14665 break;
14666
14667 case 2:
14668 step=0;
14669 break;
14670
14671 default:
14672 step=0.5;
14673 break;
14674
14675 }
14676
14677 move(step);
14678
14679 // if(d->misc1 && misc<=0 && clk3==28)
14680 if(dmisc1 && misc<=0 && clk3==28)
14681 {
14682 if(dmisc2 != 1)
14683 {
14684 if(lined_up(8,false) == dir)
14685 {
14686 // addEwpn(x,y,z,wpn,0,wdp,dir,getUID());
14687 // sfx(WAV_WAND,pan(int32_t(x)));
14688 wizzrobe_attack_for_real();
14689 fclk=30;
14690 }
14691 }
14692 else
14693 {
14694 if((zc_oldrand()%500)>=400)
14695 {
14696 wizzrobe_attack_for_real();
14697 fclk=30;
14698 }
14699 }
14700 }
14701
14702 if(misc==0 && (zc_oldrand()&127)==0)
14703 misc=2;
14704
14705 if(misc==2 && clk3==4)
14706 fix_coords();
14707
14708 if(!(charging||firing)) //should never be charging or firing for these wizzrobes
14709 {
14710 if(fclk>0)
14711 {
14712 --fclk;
14713 }
14714 }
14715
14716 }
14717
14718 void eWizzrobe::wizzrobe_newdir(int32_t homing)
14719 {
14720 // Wizzrobes shouldn't move to the edge of the screen;
14721 // if they're already there, they should move toward the center
14722 if(x<32)
14723 dir=right;
14724 else if(x>=224)
14725 dir=left;
14726 else if(y<32)
14727 dir=down;
14728 else if(y>=144)
14729 dir=up;
14730 else
14731 newdir(4,homing,spw_wizzrobe);
14732 }
14733
14734 void eWizzrobe::draw(BITMAP *dest)
14735 {
14736 // if(d->misc1 && (misc==1 || misc==3) && (clk3&1) && hp>0 && !watch && !stunclk) // phasing
14737 if(dmisc1 && (misc==1 || misc==3) && (clk3&1) && hp>0 && !watch && !stunclk && !frozenclock) // phasing
14738 return;
14739
14740 int32_t tempint=dummy_int[1];
14741 bool tempbool1=dummy_bool[1];
14742 bool tempbool2=dummy_bool[2];
14743 dummy_int[1]=fclk;
14744 dummy_bool[1]=charging;
14745 dummy_bool[2]=firing;
14746 update_enemy_frame();
14747 dummy_int[1]=tempint;
14748 dummy_bool[1]=tempbool1;
14749 dummy_bool[2]=tempbool2;
14750 enemy::draw(dest);
14751 }
14752
14753 /*********************************/
14754 /********** Bosses ***********/
14755 /*********************************/
14756
14757 eDodongo::eDodongo(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
14758 {
14759 fading=fade_flash_die;
14760 //nets+5120;
14761 if(dir==down&&y>=128)
14762 {
14763 dir=up;
14764 }
14765
14766 if(dir==right&&x>=208)
14767 {
14768 dir=left;
14769 }
14770 SIZEflags = d->SIZEflags;
14771 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
14772 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
14773 // al_trace("Enemy txsz:%i\n", txsz);
14774 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
14775 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
14776 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
14777 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
14778 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
14779 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
14780 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
14781 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
14782 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
14783 {
14784 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
14785 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
14786 }
14787
14788 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
14789 }
14790
14791 bool eDodongo::animate(int32_t index)
14792 {
14793 if(switch_hooked) return enemy::animate(index);
14794 if(dying)
14795 {
14796 return Dead(index);
14797 }
14798
14799 if(clk==0)
14800 {
14801 removearmos(x,y,ffcactivated);
14802 }
14803
14804 if(clk2) // ate a bomb
14805 {
14806 if(--clk2==0)
14807 hp-=misc; // store bomb's power in misc
14808 }
14809 else
14810 constant_walk(rate,homing,spw_clipright);
14811
14812 hxsz = (dir<=down) ? 16 : 32;
14813 // hysz = (dir>=left) ? 16 : 32;
14814
14815 return enemy::animate(index);
14816 }
14817
14818 void eDodongo::draw(BITMAP *dest)
14819 {
14820 tile=o_tile;
14821
14822 if(clk<0)
14823 {
14824 enemy::drawzcboss(dest);
14825 return;
14826 }
14827
14828 update_enemy_frame();
14829 enemy::drawzcboss(dest);
14830
14831 if(dummy_int[1]!=0) //additional tiles
14832 {
14833 tile+=dummy_int[1]; //second tile is previous tile
14834 xofs-=16; //new xofs change
14835 enemy::drawzcboss(dest);
14836 xofs+=16;
14837 }
14838
14839 }
14840
14841 int32_t eDodongo::takehit(weapon *w)
14842 {
14843 int32_t wpnId = w->id;
14844 int32_t power = w->power;
14845 int32_t wpnx = w->x;
14846 int32_t wpny = w->y;
14847
14848 if(dying || clk<0 || clk2>0 || (superman && !(superman>1 && wpnId==wSBomb)))
14849 return 0;
14850
14851 switch(wpnId)
14852 {
14853 case wPhantom:
14854 return 0;
14855
14856 case wFire:
14857 case wBait:
14858 case wWhistle:
14859 case wWind:
14860 case wSSparkle:
14861 case wFSparkle:
14862 return 0;
14863
14864 case wLitBomb:
14865 case wLitSBomb:
14866 if(abs(wpnx-((dir==right)?x+16:x)) > 7 || abs(wpny-y) > 7)
14867 return 0;
14868
14869 clk2=96;
14870 misc=power;
14871
14872 if(wpnId==wLitSBomb)
14873 item_set=isSBOMB100;
14874
14875 return 1;
14876
14877 case wBomb:
14878 case wSBomb:
14879 if(abs(wpnx-((dir==right)?x+16:x)) > 8 || abs(wpny-y) > 8)
14880 return 0;
14881
14882 stunclk=160;
14883 misc=wpnId; // store wpnId
14884 return 1;
14885
14886 case wSword:
14887 if(stunclk)
14888 {
14889 sfx(WAV_EHIT,pan(int32_t(x)));
14890 hp=0;
14891 item_set = (misc==wSBomb) ? isSBOMB100 : isBOMB100;
14892 fading=0; // don't flash
14893 return 1;
14894 }
14895
14896 [[fallthrough]];
14897 default:
14898 sfx(WAV_CHINK,pan(int32_t(x)));
14899 }
14900
14901 return 1;
14902 }
14903
14904 eDodongo2::eDodongo2(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
14905 {
14906 fading=fade_flash_die;
14907 //nets+5180;
14908 previous_dir=-1;
14909 if(dir==down&&y>=128)
14910 {
14911 dir=up;
14912 }
14913
14914 if(dir==right&&x>=208)
14915 {
14916 dir=left;
14917 }
14918 SIZEflags = d->SIZEflags;
14919 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
14920 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
14921 // al_trace("Enemy txsz:%i\n", txsz);
14922 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
14923 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
14924 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
14925 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
14926 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
14927 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
14928 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
14929 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
14930 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
14931 {
14932 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
14933 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
14934 }
14935
14936 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
14937 }
14938
14939 bool eDodongo2::animate(int32_t index)
14940 {
14941 if(switch_hooked) return enemy::animate(index);
14942 if(dying)
14943 {
14944 return Dead(index);
14945 }
14946
14947 if(clk==0)
14948 {
14949 removearmos(x,y,ffcactivated);
14950 }
14951
14952 if(clk2) // ate a bomb
14953 {
14954 if(--clk2==0)
14955 hp-=misc; // store bomb's power in misc
14956 }
14957 else
14958 constant_walk(rate,homing,spw_clipbottomright);
14959
14960 hxsz = (dir<=down) ? 16 : 32;
14961 hysz = (dir>=left) ? 16 : 32;
14962 hxofs=(dir>=left)?-8:0;
14963 hyofs=(dir<left)?-8:0;
14964
14965 return enemy::animate(index);
14966 }
14967
14968 void eDodongo2::draw(BITMAP *dest)
14969 {
14970 if(clk<0)
14971 {
14972 enemy::drawzcboss(dest);
14973 return;
14974 }
14975
14976 int32_t tempx=xofs;
14977 int32_t tempy=yofs;
14978 update_enemy_frame();
14979 enemy::drawzcboss(dest);
14980 tile+=dummy_int[1]; //second tile change
14981 xofs+=dummy_int[2]; //new xofs change
14982 yofs+=dummy_int[3]; //new yofs change
14983 enemy::drawzcboss(dest);
14984 xofs=tempx;
14985 yofs=tempy;
14986 }
14987
14988 int32_t eDodongo2::takehit(weapon *w)
14989 {
14990 int32_t wpnId = w->id;
14991 int32_t power = w->power;
14992 int32_t wpnx = w->x;
14993 int32_t wpny = w->y;
14994
14995 if(dying || clk<0 || clk2>0 || superman)
14996 return 0;
14997
14998 switch(wpnId)
14999 {
15000 case wPhantom:
15001 return 0;
15002
15003 case wFire:
15004 case wBait:
15005 case wWhistle:
15006 case wWind:
15007 case wSSparkle:
15008 case wFSparkle:
15009 return 0;
15010
15011 case wLitBomb:
15012 case wLitSBomb:
15013 switch(dir)
15014 {
15015 case up:
15016 if(abs(wpnx-x) > 7 || abs(wpny-(y-8)) > 7)
15017 return 0;
15018
15019 break;
15020
15021 case down:
15022 if(abs(wpnx-x) > 7 || abs(wpny-(y+8)) > 7)
15023 return 0;
15024
15025 break;
15026
15027 case left:
15028 if(abs(wpnx-(x-8)) > 7 || abs(wpny-y) > 7)
15029 return 0;
15030
15031 break;
15032
15033 case right:
15034 if(abs(wpnx-(x+8)) > 7 || abs(wpny-y) > 7)
15035 return 0;
15036
15037 break;
15038 }
15039
15040 // if(abs(wpnx-((dir==right)?x+8:(dir==left)?x-8:0)) > 7 || abs(wpny-((dir==down)?y+8:(dir==up)?y-8:0)) > 7)
15041 // return 0;
15042 clk2=96;
15043 misc=power;
15044
15045 if(wpnId==wLitSBomb)
15046 item_set=isSBOMB100;
15047
15048 return 1;
15049
15050 case wBomb:
15051 case wSBomb:
15052 switch(dir)
15053 {
15054 case up:
15055 if(abs(wpnx-x) > 7 || abs(wpny-(y-8)) > 7)
15056 return 0;
15057
15058 break;
15059
15060 case down:
15061 if(abs(wpnx-x) > 7 || abs(wpny-(y+8)) > 7)
15062 return 0;
15063
15064 break;
15065
15066 case left:
15067 if(abs(wpnx-(x-8)) > 7 || abs(wpny-y) > 7)
15068 return 0;
15069
15070 break;
15071
15072 case right:
15073 if(abs(wpnx-(x+8)) > 7 || abs(wpny-y) > 7)
15074 return 0;
15075
15076 break;
15077 }
15078
15079 stunclk=160;
15080 misc=wpnId; // store wpnId
15081 return 1;
15082
15083 case wSword:
15084 if(stunclk)
15085 {
15086 sfx(WAV_EHIT,pan(int32_t(x)));
15087 hp=0;
15088 item_set = (misc==wSBomb) ? isSBOMB100 : isBOMB100;
15089 fading=0; // don't flash
15090 return 1;
15091 }
15092
15093 [[fallthrough]];
15094 default:
15095 sfx(WAV_CHINK,pan(int32_t(x)));
15096 }
15097
15098 return 1;
15099 }
15100
15101 6 eAquamentus::eAquamentus(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)//enemy((zfix)176,(zfix)64,Id,Clk)
15102 6 {
15103 //these are here to bypass compiler warnings about unused arguments
15104
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( !(editorflags & ENEMY_FLAG5) )
15105 {
15106
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 x = dmisc1 ? 64 : 176;
15107
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 y = 64;
15108 2 }
15109 else { x = X; y = Y; }
15110
15111 //nets+5940;
15112
3/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15113 {
15114 1 }
15115 else
15116 {
15117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(dmisc1)
15118 {
15119 flip=1;
15120 }
15121 }
15122
15123
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)+1;
15124 2 clk3=32;
15125 2 clk2=0;
15126 2 clk4=clk;
15127 2 dir=left;
15128 2 SIZEflags = d->SIZEflags;
15129
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
15130 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
15131 // al_trace("Enemy txsz:%i\n", txsz);
15132
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
15133
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
15134
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
15135
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
15136
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
15137
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
15138 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
15139
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
15140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
15141 {
15142 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
15143 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
15144 }
15145
15146
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
15147 4 }
15148
15149 1101 bool eAquamentus::animate(int32_t index)
15150 {
15151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1101 times.
1101 if(switch_hooked) return enemy::animate(index);
15152
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 1065 times.
1101 if(dying)
15153 36 return Dead(index);
15154
15155 // fbx=x+((id==eRAQUAM)?4:-4);
15156
2/2
✓ Branch 0 taken 1060 times.
✓ Branch 1 taken 5 times.
1065 if(clk==0)
15157 {
15158 5 removearmos(x,y,ffcactivated);
15159 5 }
15160
15161 1065 fbx=x;
15162
15163 /*
15164 if (get_bit(quest_rules,qr_NEWENEMYTILES)&&id==eLAQUAM)
15165 {
15166 fbx+=16;
15167 }
15168 */
15169
2/2
✓ Branch 0 taken 1057 times.
✓ Branch 1 taken 8 times.
1065 if(--clk3==0)
15170 {
15171 // addEwpn(fbx,y,z,ewFireball,0,d->wdp,up+1);
15172 // addEwpn(fbx,y,z,ewFireball,0,d->wdp,0);
15173 // addEwpn(fbx,y,z,ewFireball,0,d->wdp,down+1);
15174 8 addEwpn(fbx,y,z,wpn,2,wdp,up,getUID(), 0, fakez);
15175 8 addEwpn(fbx,y,z,wpn,2,wdp,8,getUID(), 0, fakez);
15176 8 addEwpn(fbx,y,z,wpn,2,wdp,down,getUID(), 0, fakez);
15177 8 sfx(wpnsfx(wpn),pan(int32_t(x)));
15178 8 }
15179
15180
4/4
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 820 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 239 times.
1065 if(clk3<-80 && !(zc_oldrand()&63))
15181 {
15182 6 clk3=32;
15183 6 }
15184
15185
2/2
✓ Branch 0 taken 1048 times.
✓ Branch 1 taken 17 times.
1065 if(!((clk4+1)&63))
15186 {
15187 17 int32_t d2=(zc_oldrand()%3)+1;
15188
15189
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 13 times.
17 if(d2>=left)
15190 {
15191 13 dir=d2;
15192 13 }
15193
15194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(dmisc1)
15195 {
15196 if(x<=40)
15197 {
15198 dir=right;
15199 }
15200
15201 if(x>=104)
15202 {
15203 dir=left;
15204 }
15205 }
15206 else
15207 {
15208
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 if(x<=136)
15209 {
15210 dir=right;
15211 }
15212
15213
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 if(x>=200)
15214 {
15215 dir=left;
15216 }
15217 }
15218 17 }
15219
15220
4/4
✓ Branch 0 taken 1037 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 907 times.
✓ Branch 3 taken 130 times.
1065 if(clk4>=-1 && !((clk4+1)&7))
15221 {
15222
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 64 times.
130 if(dir==left)
15223 {
15224 66 x-=1;
15225 66 }
15226 else
15227 {
15228 64 x+=1;
15229 }
15230 130 }
15231
15232 1065 clk4=(clk4+1)%256;
15233
15234 1065 return enemy::animate(index);
15235 1101 }
15236
15237 1101 void eAquamentus::draw(BITMAP *dest)
15238 {
15239
2/2
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 687 times.
1101 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15240 {
15241 414 xofs=(dmisc1?-16:0);
15242
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 414 times.
✓ Branch 2 taken 193 times.
✓ Branch 3 taken 221 times.
414 if ( do_animation ) tile=o_tile+((clk&24)>>2)+(clk3>-32?(clk3>0?40:80):0);
15243
15244
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 396 times.
414 if(dying)
15245 {
15246 18 xofs=0;
15247 18 enemy::draw(dest);
15248 18 }
15249 else
15250 {
15251 396 drawblock(dest,15);
15252 }
15253 414 }
15254 else
15255 {
15256 687 int32_t xblockofs=((dmisc1)?-16:16);
15257 687 xofs=0;
15258
15259
4/4
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 654 times.
687 if(clk<0 || dying)
15260 {
15261 33 enemy::draw(dest);
15262 33 return;
15263 }
15264
1/2
✓ Branch 0 taken 654 times.
✗ Branch 1 not taken.
654 if ( do_animation )
15265 {
15266 // face (0=firing, 2=resting)
15267 654 tile=o_tile+((clk3>0)?0:2);
15268 654 enemy::draw(dest);
15269 // tail (
15270 654 tile=o_tile+((clk&16)?1:3);
15271 654 xofs=xblockofs;
15272 654 enemy::draw(dest);
15273 // body
15274 654 yofs+=16;
15275 654 xofs=0;
15276 654 tile=o_tile+((clk&16)?20:22);
15277 654 enemy::draw(dest);
15278 654 xofs=xblockofs;
15279 654 tile=o_tile+((clk&16)?21:23);
15280 654 enemy::draw(dest);
15281 654 yofs-=16;
15282 654 }
15283 else enemy::draw(dest);
15284 }
15285 1101 }
15286
15287 335 bool eAquamentus::hit(weapon *w)
15288 {
15289
3/6
✓ Branch 0 taken 335 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 335 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 335 times.
335 if(!(w->scriptcoldet&1) || w->fallclk || w->drownclk) return false;
15290
15291
1/2
✓ Branch 0 taken 335 times.
✗ Branch 1 not taken.
335 switch(w->id)
15292 {
15293 case wBeam:
15294 case wRefBeam:
15295 case wMagic:
15296 335 hysz=32;
15297 335 }
15298
15299
3/4
✓ Branch 0 taken 335 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 20 times.
335 bool ret = (dying || hclk>0) ? false : sprite::hit(w);
15300 335 hysz=16;
15301 335 return ret;
15302
15303 335 }
15304
15305 eGohma::eGohma(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk) // enemy((zfix)128,(zfix)48,Id,0)
15306 {
15307
15308 if ( !(editorflags & ENEMY_FLAG5) )
15309 {
15310 x = 128;
15311 y = 48;
15312 }
15313 else { x = X; y = Y; }
15314
15315 Clk=Clk;
15316 if(flags & guy_fadeflicker)
15317 {
15318 clk=0;
15319 superman = 1;
15320 fading=fade_flicker;
15321 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
15322 }
15323 else if(flags & guy_fadeinstant)
15324 {
15325 clk=0;
15326 }
15327 hxofs=-16;
15328 hxsz=48;
15329 clk4=0;
15330 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)+1;
15331 dir=zc_oldrand()%3+1;
15332 SIZEflags = d->SIZEflags;
15333 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
15334 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
15335 // al_trace("Enemy txsz:%i\n", txsz);
15336 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = tysz; if ( tysz > 1 ) extend = 3; }
15337 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = hxsz;
15338 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = hysz;
15339 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = hzsz;
15340 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = hxofs;
15341 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = hyofs;
15342 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
15343 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)xofs;
15344 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
15345 {
15346 yofs = (int32_t)yofs; //This seems to be setting to +48 or something with any value set?! -Z
15347 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
15348 }
15349
15350 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
15351
15352 //nets+5340;
15353 }
15354
15355 bool eGohma::animate(int32_t index)
15356 {
15357 if(switch_hooked) return enemy::animate(index);
15358 if(dying)
15359 return Dead(index);
15360
15361 if(fading)
15362 {
15363 if(++clk4 > 60)
15364 {
15365 clk4=0;
15366 superman=0;
15367 fading=0;
15368 clk=0;
15369
15370 }
15371 else return enemy::animate(index);
15372 }
15373
15374 if(clk==0)
15375 {
15376 if (ffcactivated) removearmosffc(ffcactivated-1);
15377 else
15378 {
15379 removearmos(zc_max(x-16, zfix(0)),y);
15380 did_armos = false;
15381 removearmos(x,y);
15382 did_armos = false;
15383 removearmos(zc_min(x+16, zfix(255)),y);
15384 }
15385 }
15386
15387 if(clk<0) return enemy::animate(index);
15388
15389 // Movement clk must be separate from animation clk because of the Clock item
15390 if(!watch)
15391 clk4++;
15392
15393 if((clk4&63)==0)
15394 {
15395 if(clk4&64)
15396 dir^=1;
15397 else
15398 dir=zc_oldrand()%3+1;
15399 }
15400
15401 if((clk&63)==3)
15402 {
15403 switch(dmisc1)
15404 {
15405 case 1:
15406 addEwpn(x,y+2,z,wpn,3,wdp,left,getUID(), 0, fakez);
15407 addEwpn(x,y+2,z,wpn,3,wdp,8,getUID(), 0, fakez);
15408 addEwpn(x,y+2,z,wpn,3,wdp,right,getUID(), 0, fakez);
15409 sfx(wpnsfx(wpn),pan(int32_t(x)));
15410 break;
15411
15412 default:
15413 if(dmisc1 != 1 && dmisc1 != 2)
15414 {
15415 addEwpn(x,y+2,z,wpn,3,wdp,8,getUID(), 0, fakez);
15416 sfx(wpnsfx(wpn),pan(int32_t(x)));
15417 sfx(wpnsfx(wpn),pan(int32_t(x)));
15418 }
15419
15420 break;
15421 }
15422 }
15423
15424 if((dmisc1 == 2)&& clk3>=16 && clk3<116)
15425 {
15426 if(!(clk3%8))
15427 {
15428 FireBreath(true);
15429 }
15430 }
15431
15432 if(clk4&1)
15433 move((zfix)1);
15434
15435 if(++clk3>=400)
15436 clk3=0;
15437
15438 return enemy::animate(index);
15439 }
15440
15441 void eGohma::draw(BITMAP *dest)
15442 {
15443 tile=o_tile;
15444
15445 if(clk<0 || dying)
15446 {
15447 enemy::drawzcboss(dest);
15448 return;
15449 }
15450
15451 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15452 {
15453 ///if ( do_animation )
15454 //Yuck. Gohma can just not have this capability right now.
15455 // left side
15456 xofs=-16;
15457 flip=0;
15458 // if(clk&16) tile=180;
15459 // else { tile=182; flip=1; }
15460 tile+=(3*((clk&48)>>4));
15461 enemy::drawzcboss(dest);
15462
15463 // right side
15464 xofs=16;
15465 // tile=(180+182)-tile;
15466 tile=o_tile;
15467 tile+=(3*((clk&48)>>4))+2;
15468 enemy::drawzcboss(dest);
15469
15470 // body
15471 xofs=0; //Gohma may need more adjustments for SIZEflags. -Z 14 Aug 2020
15472 tile=o_tile;
15473
15474 // tile+=(3*((clk&24)>>3))+2;
15475 if(clk3<16)
15476 tile+=7;
15477 else if(clk3<116)
15478 tile+=10;
15479 else if(clk3<132)
15480 tile+=7;
15481 else
15482 tile+=((clk3-132)&24)?4:1;
15483
15484 enemy::drawzcboss(dest);
15485
15486 }
15487 else
15488 {
15489 // left side
15490 xofs=-16;
15491 flip=0;
15492
15493 if(!(clk&16))
15494 {
15495 tile+=2;
15496 flip=1;
15497 }
15498
15499 enemy::draw(dest);
15500
15501 // right side
15502 tile=o_tile;
15503 xofs=16;
15504
15505 if((clk&16)) tile+=2;
15506
15507 // tile=(180+182)-tile;
15508 enemy::draw(dest);
15509
15510 // body
15511 tile=o_tile;
15512 xofs=0;
15513
15514 if(clk3<16)
15515 tile+=4;
15516 else if(clk3<116)
15517 tile+=5;
15518 else if(clk3<132)
15519 tile+=4;
15520 else tile+=((clk3-132)&8)?3:1;
15521
15522 enemy::draw(dest);
15523
15524 }
15525 }
15526
15527 int32_t eGohma::takehit(weapon *w)
15528 {
15529 int32_t wpnId = w->id;
15530 int32_t power = w->power;
15531 int32_t wpnx = w->x;
15532 int32_t wpnDir = w->dir;
15533 int32_t def = defenditemclassNew(wpnId, &power, w);
15534
15535 if(def < 0)
15536 {
15537 if(!((wpnDir==up || wpnDir==l_up || wpnDir==r_up) && abs(int32_t(x)-wpnx)<=8 && clk3>=16 && clk3<116))
15538 {
15539 sfx(WAV_CHINK,pan(int32_t(x)));
15540 return 1;
15541 }
15542 }
15543
15544 return enemy::takehit(w);
15545 }
15546
15547 eLilDig::eLilDig(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
15548 {
15549 count_enemy=(id==(id&0xFFF));
15550 //nets+4360+(((id&0xFF)-eDIGPUP2)*40);
15551 SIZEflags = d->SIZEflags;
15552 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
15553 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
15554 // al_trace("Enemy txsz:%i\n", txsz);
15555 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
15556 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
15557 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
15558 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
15559 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
15560 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
15561 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
15562 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
15563 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
15564 {
15565 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
15566 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
15567 }
15568
15569 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
15570 }
15571
15572 bool eLilDig::animate(int32_t index)
15573 {
15574 if(switch_hooked) return enemy::animate(index);
15575 if(dying)
15576 return Dead(index);
15577
15578 if(clk==0)
15579 {
15580 removearmos(x,y,ffcactivated);
15581 }
15582
15583 if(misc<=128)
15584 {
15585 if(!(++misc&31))
15586 step+=0.25;
15587 }
15588
15589 variable_walk_8(rate,homing,hrate,spw_floater);
15590 return enemy::animate(index);
15591 }
15592
15593 void eLilDig::draw(BITMAP *dest)
15594 {
15595 tile = o_tile;
15596 // tile = 160;
15597 int32_t fdiv = frate/4;
15598 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
15599 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
15600 efrate:((clk>=(frate>>1))?1:0);
15601
15602 if ( do_animation )
15603 {
15604 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15605 {
15606 switch(dir-8) //directions get screwed up after 8. *shrug*
15607 {
15608 case up: //u
15609 flip=0;
15610 break;
15611
15612 case l_up: //d
15613 flip=0;
15614 tile+=4;
15615 break;
15616
15617 case l_down: //l
15618 flip=0;
15619 tile+=8;
15620 break;
15621
15622 case left: //r
15623 flip=0;
15624 tile+=12;
15625 break;
15626
15627 case r_down: //ul
15628 flip=0;
15629 tile+=20;
15630 break;
15631
15632 case down: //ur
15633 flip=0;
15634 tile+=24;
15635 break;
15636
15637 case r_up: //dl
15638 flip=0;
15639 tile+=28;
15640 break;
15641
15642 case right: //dr
15643 flip=0;
15644 tile+=32;
15645 break;
15646 }
15647
15648 tile+=f2;
15649 }
15650 else
15651 {
15652 tile+=(clk>=6)?1:0;
15653 }
15654 }
15655
15656 enemy::draw(dest);
15657 }
15658
15659 eBigDig::eBigDig(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
15660 {
15661 superman=1;
15662
15663 SIZEflags = d->SIZEflags;
15664 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
15665 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
15666 // al_trace("Enemy txsz:%i\n", txsz);
15667 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
15668 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
15669 else hxsz=32;
15670 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
15671 else hysz=32;
15672 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
15673 else hzsz=16; // hard to jump.
15674 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
15675 else hxofs=-8;
15676 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
15677 else hyofs=-8;
15678 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
15679 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
15680 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
15681 {
15682 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
15683 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
15684 }
15685
15686 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
15687
15688
15689 }
15690
15691 bool eBigDig::animate(int32_t index)
15692 {
15693 if(switch_hooked) return enemy::animate(index);
15694 if(dying)
15695 return Dead(index);
15696
15697 if(clk==0)
15698 {
15699 removearmos(x,y,ffcactivated);
15700 }
15701
15702 switch(misc)
15703 {
15704 case 0:
15705 variable_walk_8(rate,homing,hrate,spw_floater,-8,-16,23,23);
15706 break;
15707
15708 case 1:
15709 ++misc;
15710 break;
15711
15712 case 2:
15713 for(int32_t i=0; i<dmisc5; i++)
15714 {
15715 addenemy(x,y,dmisc1+0x1000,-15);
15716 }
15717
15718 for(int32_t i=0; i<dmisc6; i++)
15719 {
15720 addenemy(x,y,dmisc2+0x1000,-15);
15721 }
15722
15723 for(int32_t i=0; i<dmisc7; i++)
15724 {
15725 addenemy(x,y,dmisc3+0x1000,-15);
15726 }
15727
15728 for(int32_t i=0; i<dmisc8; i++)
15729 {
15730 addenemy(x,y,dmisc4+0x1000,-15);
15731 }
15732
15733 if(itemguy) // Hand down the carried item
15734 {
15735 guycarryingitem = guys.Count()-1;
15736 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
15737 itemguy = false;
15738 }
15739
15740 stop_bgsfx(index);
15741
15742 if(deadsfx > 0) sfx(deadsfx,pan(int32_t(x)));
15743
15744 return true;
15745 }
15746
15747 return enemy::animate(index);
15748 }
15749
15750 void eBigDig::draw(BITMAP *dest)
15751 {
15752 if(anim!=aDIG)
15753 {
15754 update_enemy_frame();
15755 xofs-=8;
15756 yofs-=8;
15757 drawblock(dest,15);
15758 xofs+=8;
15759 yofs+=8;
15760 return;
15761 }
15762
15763 tile = o_tile;
15764 int32_t fdiv = frate/4;
15765 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
15766
15767 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
15768 efrate:((clk>=(frate>>1))?1:0);
15769
15770 if ( do_animation )
15771 {
15772 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15773 {
15774 switch(dir-8) //directions get screwed up after 8. *shrug*
15775 {
15776 case up: //u
15777 flip=0;
15778 break;
15779
15780 case l_up: //d
15781 flip=0;
15782 tile+=8;
15783 break;
15784
15785 case l_down: //l
15786 flip=0;
15787 tile+=40;
15788 break;
15789
15790 case left: //r
15791 flip=0;
15792 tile+=48;
15793 break;
15794
15795 case r_down: //ul
15796 flip=0;
15797 tile+=80;
15798 break;
15799
15800 case down: //ur
15801 flip=0;
15802 tile+=88;
15803
15804 break;
15805
15806 case r_up: //dl
15807 flip=0;
15808 tile+=120;
15809 break;
15810
15811 case right: //dr
15812 flip=0;
15813 tile+=128;
15814 break;
15815 }
15816
15817 tile+=(f2*2);
15818 }
15819 else
15820 {
15821 tile+=(f2)?0:2;
15822 flip=(clk&1)?1:0;
15823 }
15824 }
15825
15826 xofs-=8;
15827 yofs-=8;
15828 drawblock(dest,15);
15829 xofs+=8;
15830 yofs+=8;
15831 }
15832
15833 int32_t eBigDig::takehit(weapon *w)
15834 {
15835 int32_t wpnId = w->id;
15836
15837 if(wpnId==wWhistle && misc==0)
15838 misc=1;
15839
15840 return 0;
15841 }
15842
15843 /*
15844 eGanon::eGanon(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
15845 {
15846 hxofs=hyofs=8;
15847 hzsz=16; //can't be jumped.
15848 clk2=70;
15849 misc=-1;
15850 mainguy=!getmapflag();
15851 }
15852
15853 bool eGanon::animate(int32_t index)
15854 {
15855 if(switch_hooked) return enemy::animate(index);
15856 if(dying)
15857
15858 return Dead(index);
15859
15860 if(clk==0)
15861 {
15862 removearmos(x,y,ffcactivated);
15863 }
15864
15865 switch(misc)
15866 {
15867 case -1:
15868 misc=0;
15869
15870 case 0:
15871 if(++clk2>72 && !(zc_oldrand()&3))
15872 {
15873 addEwpn(x,y,z,wpn,3,wdp,dir,getUID());
15874 sfx(wpnsfx(wpn),pan(int32_t(x)));
15875 clk2=0;
15876 }
15877
15878 Stunclk=0;
15879 constant_walk(rate,homing,spw_none);
15880 break;
15881
15882 case 1:
15883 case 2:
15884 if(--Stunclk<=0)
15885 {
15886 int32_t r=zc_oldrand();
15887
15888 if(r&1)
15889 {
15890 y=96;
15891
15892 if(r&2)
15893 x=160;
15894 else
15895 x=48;
15896
15897 if(tooclose(x,y,48))
15898 x=208-x;
15899 }
15900
15901 //if ( editorflags & ENEMY_FLAG15 && current_item_id(itype_amulet,false) >= 2 ) //visible to Amulet 2
15902 //{
15903 // loadpalset(9,pSprite(spBROWN)); //make Ganon visible?
15904 // }
15905 // else
15906 // {
15907 loadpalset(csBOSS,pSprite(d->bosspal));
15908 // }
15909 misc=0;
15910 }
15911
15912 break;
15913
15914 case 3:
15915 {
15916 if(hclk>0)
15917 break;
15918
15919 misc=4;
15920 clk=0;
15921 hxofs=1000;
15922 loadpalset(9,pSprite(spPILE));
15923 music_stop();
15924 stop_sfx(WAV_ROAR);
15925
15926 if(deadsfx>0) sfx(deadsfx,pan(int32_t(x)));
15927
15928 sfx(WAV_GANON);
15929 //Ganon's dustpile; fall in sideview. -Z
15930 item *dustpile = new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0);
15931 dustpile->linked_parent = eeGANON;
15932 setmapflag();
15933 //items.add(new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0));
15934 break;
15935 }
15936
15937 case 4:
15938 if(clk>=80)
15939 {
15940 misc=5;
15941
15942 if(getmapflag())
15943 {
15944 game->lvlitems[dlevel]|=liBOSS;
15945 //play_DmapMusic();
15946 playLevelMusic();
15947 return true;
15948 }
15949
15950 sfx(WAV_CLEARED);
15951 items.add(new item(x+8,y+8,(zfix)0,iBigTri,ipBIGTRI,0));
15952 setmapflag();
15953 }
15954
15955 break;
15956 }
15957
15958 //if ( editorflags & ENEMY_FLAG15 ) //visible to Amulet 2
15959 //{
15960 //if ( current_item_id(itype_amulet,false) >= 2 )
15961 //{
15962 /// loadpalset(9,pSprite(spBROWN)); //make Ganon visible?
15963 //}
15964 //}
15965
15966
15967 return enemy::animate(index);
15968 }
15969
15970
15971 int32_t eGanon::takehit(weapon *w)
15972 {
15973 //these are here to bypass compiler warnings about unused arguments
15974 int32_t wpnId = w->id;
15975 int32_t power = w->power;
15976 int32_t enemyHitWeapon = w->parentitem;
15977
15978 switch(misc)
15979 {
15980 case 0:
15981 {
15982 //if we're not using the editor defences, and Ganon isn't hit by a sword, return.
15983 if(wpnId!=wSword && !(editorflags & ENEMY_FLAG14))
15984 return 0;
15985
15986 //if we are not using the new defences, just reduce his HP
15987 if (!(editorflags & ENEMY_FLAG14))
15988 {
15989 hp-=power;
15990 if(hp>0)
15991 {
15992 misc=1;
15993 Stunclk=64;
15994 }
15995 else
15996 {
15997 loadpalset(csBOSS,pSprite(spBROWN));
15998 misc=2;
15999 Stunclk=284;
16000 hp=guysbuf[id&0xFFF].hp; //16*game->get_hero_dmgmult();
16001 }
16002
16003 sfx(WAV_EHIT,pan(int32_t(x)));
16004
16005 if(hitsfx>0) sfx(hitsfx,pan(int32_t(x)));
16006
16007 return 1;
16008 }
16009 //otherwise, resolve his defence.
16010 else
16011 {
16012 int32_t def = enemy::takehit(w); //This works, but it instantly kills him if it does enough damage.
16013 if(hp>0)
16014 {
16015 misc=1;
16016 Stunclk=64;
16017 }
16018 else
16019 {
16020 loadpalset(csBOSS,pSprite(spBROWN));
16021 misc=2;
16022 Stunclk=284;
16023 hp=guysbuf[id&0xFFF].hp; //16*game->get_hero_dmgmult();
16024 }
16025
16026 sfx(WAV_EHIT,pan(int32_t(x)));
16027
16028 if(hitsfx>0) sfx(hitsfx,pan(int32_t(x)));
16029
16030
16031 return 1;
16032 }
16033 }
16034 case 2:
16035 {
16036 if
16037 (
16038 ( dmisc14 > 0 && !enemyHitWeapon == dmisc14 ) //special weapon needed to kill ganon specified in editor
16039 || //or nothing specified, use silver arrows+
16040 ( dmisc14 <= 0 && (wpnId!=wArrow || (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_arrow))<4))
16041 )
16042 return 0;
16043 {
16044 misc=3;
16045 hclk=81;
16046 loadpalset(9,pSprite(spBROWN));
16047 return 1;
16048 }
16049
16050 }
16051 }
16052
16053 return 0;
16054 }
16055
16056 void eGanon::draw(BITMAP *dest)
16057 {
16058 switch(misc)
16059 {
16060 case 0:
16061 if((clk&3)==3)
16062 tile=(zc_oldrand()%5)*2+o_tile;
16063
16064 if(db!=999)
16065 break;
16066
16067 case 2:
16068 if(Stunclk<64 && (Stunclk&1) )
16069 {
16070 if
16071 (
16072 ( (editorflags & ENEMY_FLAG1) && current_item_power(itype_amulet) >= 2 && (editorflags & ENEMY_FLAG15) )
16073 ||
16074 ( (editorflags & ENEMY_FLAG2) && (game->item[dmisc13]) && (editorflags & ENEMY_FLAG15) )
16075 )
16076 {
16077 goto ganon_draw; //draw his weapons if we can see him
16078 }
16079 break;
16080 }
16081
16082 case -1:
16083 tile=o_tile;
16084
16085 //fall through
16086 case 1:
16087 case 3:
16088 ganon_draw:
16089 drawblock(dest,15);
16090 break;
16091
16092 case 4:
16093 draw_guts(dest);
16094 draw_flash(dest);
16095 break;
16096 }
16097
16098 if ( editorflags & ENEMY_FLAG1 ) //visible to Amulet 2
16099 {
16100 if
16101 (
16102 ( (editorflags & ENEMY_FLAG1) && current_item_power(itype_amulet) >= 2 && (editorflags & ENEMY_FLAG15) )
16103 ||
16104 ( (editorflags & ENEMY_FLAG2) && (game->item[dmisc13]) && (editorflags & ENEMY_FLAG15) )
16105 )
16106 {
16107 draw_guts(dest); //makes his shots visible, but not him
16108 draw_flash(dest);
16109 }
16110 }
16111 }
16112
16113 void eGanon::draw_guts(BITMAP *dest)
16114 {
16115 int32_t c = zc_min(clk>>3,8);
16116 tile = clk<24 ? 74 : 75;
16117 overtile16(dest,tile,x+8,y+c+playing_field_offset,9,0);
16118 overtile16(dest,tile,x+8,y+16-c+playing_field_offset,9,0);
16119 overtile16(dest,tile,x+c,y+8+playing_field_offset,9,0);
16120 overtile16(dest,tile,x+16-c,y+8+playing_field_offset,9,0);
16121 overtile16(dest,tile,x+c,y+c+playing_field_offset,9,0);
16122 overtile16(dest,tile,x+16-c,y+c+playing_field_offset,9,0);
16123 overtile16(dest,tile,x+c,y+16-c+playing_field_offset,9,0);
16124 overtile16(dest,tile,x+16-c,y+16-c+playing_field_offset,9,0);
16125 }
16126
16127 void eGanon::draw_flash(BITMAP *dest)
16128 {
16129
16130 int32_t c = clk-(clk>>2);
16131 cs = (frame&3)+6;
16132 overtile16(dest,194,x+8,y+8-clk+playing_field_offset,cs,0);
16133 overtile16(dest,194,x+8,y+8+clk+playing_field_offset,cs,2);
16134 overtile16(dest,195,x+8-clk,y+8+playing_field_offset,cs,0);
16135 overtile16(dest,195,x+8+clk,y+8+playing_field_offset,cs,1);
16136 overtile16(dest,196,x+8-c,y+8-c+playing_field_offset,cs,0);
16137 overtile16(dest,196,x+8+c,y+8-c+playing_field_offset,cs,1);
16138 overtile16(dest,196,x+8-c,y+8+c+playing_field_offset,cs,2);
16139 overtile16(dest,196,x+8+c,y+8+c+playing_field_offset,cs,3);
16140 }
16141 */
16142
16143 eGanon::eGanon(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
16144 {
16145 hxofs=hyofs=8;
16146 if (editorflags & ENEMY_FLAG3)
16147 {
16148 hxofs = 4;
16149 hyofs = 4;
16150 hxsz = 24;
16151 hysz = 24;
16152 SIZEflags|=guyflagOVERRIDE_HIT_WIDTH;
16153 SIZEflags|=guyflagOVERRIDE_HIT_HEIGHT;
16154 }
16155 hzsz=16; //can't be jumped.
16156 clk2=70;
16157 misc=-1;
16158 mainguy=(!getmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM) || (tmpscr->flags9&fBELOWRETURN));
16159 }
16160
16161 bool eGanon::animate(int32_t index) //DO NOT ADD a check for do_animation to this version of GANON!! -Z
16162 {
16163 if(dying)
16164
16165 return Dead(index);
16166
16167 if(clk==0)
16168 {
16169 removearmos(x,y,ffcactivated);
16170 }
16171
16172 switch(misc)
16173 {
16174 case -1:
16175 misc=0;
16176 [[fallthrough]];
16177 case 0:
16178 if(++clk2>72 && !(zc_oldrand()&3))
16179 {
16180 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
16181 sfx(wpnsfx(wpn),pan(int32_t(x)));
16182 clk2=0;
16183 }
16184
16185 Stunclk=0;
16186 constant_walk(rate,homing,spw_none);
16187 break;
16188
16189 case 1:
16190 case 2:
16191 if(--Stunclk<=0)
16192 {
16193 int32_t r=zc_oldrand();
16194
16195 if(r&1)
16196 {
16197 y=96;
16198
16199 if(r&2)
16200 x=160;
16201 else
16202 x=48;
16203
16204 if(tooclose(x,y,48))
16205 x=208-x;
16206 }
16207
16208 loadpalset(csBOSS,pSprite(d->bosspal));
16209 misc=0;
16210 }
16211
16212 break;
16213
16214 case 3:
16215 {
16216 if(hclk>0)
16217 break;
16218
16219 misc=4;
16220 clk=0;
16221 hxofs=1000;
16222 loadpalset(9,pSprite(spPILE));
16223 music_stop();
16224 stop_sfx(WAV_ROAR);
16225
16226 if(deadsfx>0) sfx(deadsfx,pan(int32_t(x)));
16227
16228 sfx(WAV_GANON);
16229 //Ganon's dustpile; fall in sideview. -Z
16230 //item *dustpile = new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0);
16231 //dustpile->miscellaneous[31] = eeGANON;
16232 items.add(new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0));
16233 item *dustpile = NULL;
16234 //dustpile = (item *)items.spr(items.Count() - 1)->getUID();
16235 dustpile = (item *)items.spr(items.Count() - 1);
16236 dustpile->linked_parent = eeGANON; //was miscellaneous[31]
16237 //setmapflag(); //Could be why the Triforce doesn't drop. Disabling this now. -Z ( 6th March, 2019 )
16238 //items.add(new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0));
16239 break;
16240 }
16241
16242 case 4:
16243 if(clk>=80)
16244 {
16245 misc=5;
16246
16247 //game->lvlitems[dlevel]|=liBOSS;
16248
16249 sfx(WAV_CLEARED);
16250 //Add the big TF over the ashes!
16251 for(word q = 0; q < items.Count(); q++)
16252 {
16253 item *ashes = (item*)items.spr(q);
16254 if ( ashes->linked_parent == eeGANON && (ashes->pickup&ipDUMMY))
16255 {
16256 //Z_scripterrlog("Found correct dustpile!\n");
16257 items.add(new item(ashes->x,ashes->y,(zfix)0,iBigTri,ipBIGTRI,0));
16258 item *bigtriforce = NULL;
16259 bigtriforce = (item *)items.spr(items.Count() - 1);
16260 bigtriforce->linked_parent = eeGANON;
16261 }
16262 }
16263 //setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
16264 //game->lvlitems[dlevel]|=liBOSS; // if we had more rule bits, we could mark him dead so that he does not respawn. -Z
16265 }
16266
16267 break;
16268 case 5: return true;
16269 }
16270
16271 return enemy::animate(index);
16272 }
16273
16274
16275 int32_t eGanon::takehit(weapon *w)
16276 {
16277 //these are here to bypass compiler warnings about unused arguments
16278 int32_t wpnId = w->id;
16279 int32_t power = w->power;
16280 int32_t enemyHitWeapon = w->parentitem;
16281
16282 switch(misc)
16283 {
16284 case 0:
16285 if(wpnId!=wSword)
16286 return 0;
16287
16288 hp-=power;
16289
16290 if(hp>0)
16291 {
16292 misc=1;
16293 Stunclk=64;
16294 }
16295 else
16296 {
16297 loadpalset(csBOSS,pSprite(spBROWN));
16298 misc=2;
16299 Stunclk=284;
16300 hp=guysbuf[id&0xFFF].hp; //16*game->get_hero_dmgmult();
16301 }
16302
16303 sfx(WAV_EHIT,pan(int32_t(x)));
16304
16305 if(hitsfx>0) sfx(hitsfx,pan(int32_t(x)));
16306
16307 return 1;
16308
16309 case 2:
16310 if(wpnId!=wArrow || (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_arrow))<4)
16311 return 0;
16312
16313 misc=3;
16314 hclk=81;
16315 loadpalset(9,pSprite(spBROWN));
16316 return 1;
16317 }
16318
16319 return 0;
16320 }
16321
16322 void eGanon::draw(BITMAP *dest)
16323 {
16324 switch(misc)
16325 {
16326 case 0:
16327 if((clk&3)==3)
16328 tile=(zc_oldrand()%5)*2+o_tile;
16329
16330 if ( (editorflags & ENEMY_FLAG1) && current_item_power(itype_amulet) >= 2 ) //ganon is visible to level 2 amulet
16331 {
16332
16333 if ( editorflags & ENEMY_FLAG16 ) //draw cloaked
16334 {
16335 int odraw = drawstyle;
16336 drawstyle = 2;
16337 drawblock(dest,15);
16338 drawstyle = odraw;
16339 }
16340 else
16341 {
16342 drawblock(dest,15);
16343 }
16344 break;
16345
16346 }
16347 else if ( (editorflags & ENEMY_FLAG2) && (game->item[dmisc13]) )
16348 {
16349 if ( editorflags & ENEMY_FLAG16 ) //draw cloaked
16350 {
16351 int odraw = drawstyle;
16352 drawstyle = 2;
16353 drawblock(dest,15);
16354 drawstyle = odraw;
16355 }
16356 else
16357 {
16358 drawblock(dest,15);
16359 }
16360 break;
16361 }
16362 if(db!=999)
16363 break;
16364 [[fallthrough]];
16365 case 2:
16366 if(Stunclk<64 && (Stunclk&1))
16367 break;
16368 [[fallthrough]];
16369 case -1:
16370 tile=o_tile;
16371
16372 [[fallthrough]];
16373 case 1:
16374 case 3:
16375 drawblock(dest,15);
16376 break;
16377
16378 case 4:
16379 draw_guts(dest);
16380 draw_flash(dest);
16381 break;
16382 }
16383 }
16384
16385 void eGanon::draw_guts(BITMAP *dest)
16386 {
16387 int32_t c = zc_min(clk>>3,8);
16388 tile = clk<24 ? 74 : 75;
16389 overtile16(dest,tile,x+8,y+c+playing_field_offset,9,0);
16390 overtile16(dest,tile,x+8,y+16-c+playing_field_offset,9,0);
16391 overtile16(dest,tile,x+c,y+8+playing_field_offset,9,0);
16392 overtile16(dest,tile,x+16-c,y+8+playing_field_offset,9,0);
16393 overtile16(dest,tile,x+c,y+c+playing_field_offset,9,0);
16394 overtile16(dest,tile,x+16-c,y+c+playing_field_offset,9,0);
16395 overtile16(dest,tile,x+c,y+16-c+playing_field_offset,9,0);
16396 overtile16(dest,tile,x+16-c,y+16-c+playing_field_offset,9,0);
16397 }
16398
16399 void eGanon::draw_flash(BITMAP *dest)
16400 {
16401
16402 int32_t c = clk-(clk>>2);
16403 cs = (frame&3)+6;
16404 overtile16(dest,194,x+8,y+8-clk+playing_field_offset,cs,0);
16405 overtile16(dest,194,x+8,y+8+clk+playing_field_offset,cs,2);
16406 overtile16(dest,195,x+8-clk,y+8+playing_field_offset,cs,0);
16407 overtile16(dest,195,x+8+clk,y+8+playing_field_offset,cs,1);
16408 overtile16(dest,196,x+8-c,y+8-c+playing_field_offset,cs,0);
16409 overtile16(dest,196,x+8+c,y+8-c+playing_field_offset,cs,1);
16410 overtile16(dest,196,x+8-c,y+8+c+playing_field_offset,cs,2);
16411 overtile16(dest,196,x+8+c,y+8+c+playing_field_offset,cs,3);
16412 }
16413
16414 void getBigTri(int32_t id2)
16415 {
16416 /*
16417 *************************
16418 * BIG TRIFORCE SEQUENCE *
16419 *************************
16420 0 BIGTRI out, WHITE flash in
16421 4 WHITE flash out, PILE cset white
16422 8 WHITE in
16423 ...
16424 188 WHITE out
16425 191 PILE cset red
16426 200 top SHUTTER opens
16427 209 bottom SHUTTER opens
16428 */
16429 sfx(itemsbuf[id2].playsound);
16430 guys.clear();
16431
16432 if(itemsbuf[id2].flags & ITEM_GAMEDATA)
16433 {
16434 game->lvlitems[dlevel]|=liTRIFORCE;
16435 }
16436
16437 setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
16438
16439 draw_screen(tmpscr);
16440
16441 for(int32_t f=0; f<24*8 && !Quit; f++)
16442 {
16443 if(f==4)
16444 {
16445 for(int32_t i=1; i<16; i++)
16446 {
16447 RAMpal[CSET(9)+i]=_RGB(63,63,63);
16448 }
16449 }
16450
16451 if((f&7)==0)
16452 {
16453 for(int32_t cs=2; cs<5; cs++)
16454 {
16455 for(int32_t i=1; i<16; i++)
16456 {
16457 RAMpal[CSET(cs)+i]=_RGB(63,63,63);
16458 }
16459 }
16460
16461 refreshpal=true;
16462 }
16463
16464 if((f&7)==4)
16465 {
16466 if(currscr<128) loadlvlpal(DMaps[currdmap].color);
16467 else loadlvlpal(0xB);
16468 }
16469
16470 if(f==191)
16471 {
16472 loadpalset(9,pSprite(spPILE));
16473 }
16474
16475 advanceframe(true);
16476 }
16477
16478 //play_DmapMusic();
16479 playLevelMusic();
16480
16481 if(itemsbuf[id2].flags & ITEM_FLAG1 && currscr < 128)
16482 {
16483 Hero.dowarp(1,0); //side warp
16484 }
16485 }
16486
16487 /**********************************/
16488 /*** Multiple-Segment Enemies ***/
16489 /**********************************/
16490
16491
16492 //! No. I am not adding SIZEflags to Moldorm and Lanmola. -Z 12 Aug 2020
16493 eMoldorm::eMoldorm(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
16494 {
16495 if( !(editorflags & ENEMY_FLAG5) )
16496 {
16497 x=128;
16498 y=48;
16499 }
16500 //else { x = X; y = Y; }
16501 dir=(zc_oldrand()&7)+8;
16502 superman=1;
16503 fading=fade_invisible;
16504 hxofs=1000;
16505 segcnt=clk;
16506 segid=Id|0x1000;
16507 clk=0;
16508 id=guys.Count();
16509 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
16510 tile=o_tile;
16511 hitdir = -1;
16512 stickclk = 0;
16513
16514 /*
16515 if (get_bit(quest_rules,qr_NEWENEMYTILES))
16516 {
16517 tile=nets+1220;
16518 }
16519 else
16520 {
16521 tile=57;
16522 }
16523 */
16524 }
16525
16526 bool eMoldorm::animate(int32_t index)
16527 {
16528 if(switch_hooked) return enemy::animate(index);
16529 int32_t max_y = isdungeon() ? 100 : 100+28; //warning: Ugly hack. -Z
16530 if ( y > (max_y) )
16531 {
16532 ++stickclk; //Keep Moldorm from pacinn the bottom row or leaving the screen via the bottom edge. -Z 8th Sept, 2019
16533 //Z_scripterrlog("Stickclk is %d\n", stickclk);
16534 }
16535 if ( stickclk > 45 )
16536 {
16537 stickclk = 0;
16538 newdir_8_old(rate,homing,spw_floater); //chage dir to keep from getting stuck.
16539 }
16540
16541
16542 if(clk==0)
16543 {
16544 removearmos(x,y,ffcactivated);
16545 }
16546
16547 if(clk2)
16548 {
16549 if(--clk2 == 0)
16550 {
16551 if(flags&guy_neverret)
16552 never_return(index);
16553
16554 if(!dmisc2 || (editorflags & ENEMY_FLAG6))
16555 leave_item();
16556
16557 stop_bgsfx(index);
16558 return true;
16559 }
16560 }
16561 else
16562 {
16563 if(stunclk>0)
16564 stunclk=0;
16565 constant_walk_8_old(rate,homing,spw_floater);
16566
16567
16568 misc=dir;
16569
16570 // If any higher-numbered segments were killed, segcnt can be too high,
16571 // leading to a crash
16572 if(index+segcnt>=guys.Count())
16573 segcnt=guys.Count()-index-1;
16574
16575 for(int32_t i=index+1; i<index+segcnt+1; i++)
16576 {
16577 enemy* segment=((enemy*)guys.spr(i));
16578
16579 // More validation - if segcnt was wrong, this may not
16580 // actually be a Moldorm segment
16581 if(segment->id!=segid)
16582 {
16583 segcnt=i-index-1;
16584 break;
16585 }
16586
16587 if(i==index+1)
16588 {
16589 x=segment->x;
16590 y=segment->y;
16591 }
16592
16593 segment->o_tile=tile; //I refuse to fuck with adding scripttile to segmented enemies. -Z
16594 //Script your own blasted segmented bosses!! -Z
16595 segment->parent_script_UID = this->script_UID;
16596 if((i==index+segcnt)&&(i!=index+1)) //tail
16597 {
16598 segment->dummy_int[1]=2;
16599 }
16600 else
16601 {
16602 segment->dummy_int[1]=1;
16603 }
16604
16605 if(i==index+1) //head
16606 {
16607 segment->dummy_int[1]=0;
16608 }
16609
16610 if(segment->hp <= 0)
16611 {
16612 int32_t offset=1;
16613
16614 for(int32_t j=i; j<index+segcnt; j++)
16615 {
16616 // Triple-check
16617 if(((enemy*)guys.spr(j+1))->id!=segid)
16618 {
16619 segcnt=j-index+1; // Add 1 because of --segcnt below
16620 break;
16621 }
16622 zc_swap(((enemy*)guys.spr(j))->hp,((enemy*)guys.spr(j+1))->hp);
16623 zc_swap(((enemy*)guys.spr(j))->hclk,((enemy*)guys.spr(j+1))->hclk);
16624 }
16625
16626 segment->hclk=33;
16627 --segcnt;
16628 --i; // Recheck the same index in case multiple segments died at once
16629 }
16630 }
16631
16632 if(segcnt==0)
16633 {
16634 clk2=19;
16635
16636 x=guys.spr(index+1)->x;
16637 y=guys.spr(index+1)->y;
16638 }
16639 }
16640
16641 return false;
16642 }
16643
16644 esMoldorm::esMoldorm(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
16645 {
16646 if( !(editorflags & ENEMY_FLAG5) )
16647 {
16648 x=128;
16649 y=48;
16650 }
16651
16652 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
16653 hyofs=4;
16654 hxsz=hysz=8;
16655 hxofs=1000;
16656 mainguy=count_enemy=false;
16657 parentclk = 0;
16658 bgsfx=-1;
16659 flags&=~guy_neverret;
16660 //deadsfx = WAV_EDEAD;
16661 isCore = false;
16662 }
16663
16664 bool esMoldorm::animate(int32_t index)
16665 {
16666 if(switch_hooked) return enemy::animate(index);
16667 // Shouldn't be possible, but better to be sure
16668 if(index==0)
16669 dying=true;
16670
16671 if(dying)
16672 {
16673 if(!dmisc2)
16674 item_set=0;
16675
16676 return Dead(index);
16677 }
16678
16679 if(clk>=0)
16680 {
16681 hxofs=4;
16682 step=((enemy*)guys.spr(index-1))->step;
16683
16684 if(parentclk == 0)
16685 {
16686 misc=dir;
16687 dir=((enemy*)guys.spr(index-1))->misc;
16688 //do alignment, as in parent's animation :-/ -DD
16689 x.doFloor();
16690 y.doFloor();
16691 }
16692
16693 parentclk=(parentclk+1)%((int32_t)(8.0/step));
16694
16695 if(!watch)
16696 {
16697 sprite::move(step);
16698 }
16699 }
16700
16701 return enemy::animate(index);
16702 }
16703
16704 int32_t esMoldorm::takehit(weapon *w)
16705 {
16706 if(enemy::takehit(w))
16707 return (w->id==wSBomb) ? 1 : 2; // force it to wait a frame before checking sword attacks again
16708
16709 return 0;
16710 }
16711
16712 void esMoldorm::draw(BITMAP *dest)
16713 {
16714 tile=o_tile;
16715 int32_t fdiv = frate/4;
16716 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
16717
16718 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
16719 efrate:((clk>=(frate>>1))?1:0);
16720
16721 if(get_bit(quest_rules,qr_NEWENEMYTILES))
16722 {
16723 tile+=dummy_int[1]*40;
16724
16725 if(dir<8)
16726 {
16727 flip=0;
16728 tile+=4*zc_max(dir, 0); // dir is -1 if trapped
16729
16730 if(dir>3) // Skip to the next row for diagonals
16731 tile+=4;
16732 }
16733 else
16734 {
16735 switch(dir-8) //directions get screwed up after 8. *shrug*
16736 {
16737 case up: //u
16738 flip=0;
16739 break;
16740
16741 case l_up: //d
16742 flip=0;
16743 tile+=4;
16744 break;
16745
16746 case l_down: //l
16747 flip=0;
16748 tile+=8;
16749 break;
16750
16751 case left: //r
16752 flip=0;
16753 tile+=12;
16754 break;
16755
16756 case r_down: //ul
16757 flip=0;
16758 tile+=20;
16759 break;
16760
16761 case down: //ur
16762 flip=0;
16763 tile+=24;
16764 break;
16765
16766 case r_up: //dl
16767 flip=0;
16768 tile+=28;
16769 break;
16770
16771 case right: //dr
16772 flip=0;
16773 tile+=32;
16774 break;
16775 }
16776 }
16777
16778 tile+=f2;
16779 }
16780
16781 if(clk>=0)
16782 enemy::draw(dest);
16783 }
16784
16785 eLanmola::eLanmola(zfix X,zfix Y,int32_t Id,int32_t Clk) : eBaseLanmola(X,Y,Id,Clk)
16786 {
16787 if( !(editorflags & ENEMY_FLAG5) )
16788 {
16789 x=64;
16790 y=80;
16791 }
16792 //else { x = X; y = Y; }
16793 //zprint2("lanmola index is %d\n", index);
16794 //byte legaldirs = 0;
16795 int32_t incr = 16;
16796 //int32_t possiiblepos = 0;
16797 //int32_t positions[8] = {0};
16798
16799 //Don't spawn in pits.
16800 if ( m_walkflag_simple(x, y) )
16801 {
16802 //zprint2("Can't spawn here.\n");
16803 for ( ; incr < 240; incr += 16 )
16804 {
16805 //move if we spawn over a pit
16806 //check each direction
16807 if ( !m_walkflag_simple(x-incr, y) ) //legaldirs |= 0x1; //left
16808 {
16809 //zprint2("Spawn adjustment: -x (%d)\n", incr);
16810 x-=incr; break;
16811 }
16812 else if ( !m_walkflag_simple(x+incr, y) ) //legaldirs |= 0x2; //right
16813 {
16814 //zprint2("Spawn adjustment: +x (%d)\n", incr);
16815 x+=incr; break;
16816 }
16817 else if ( !m_walkflag_simple(x-incr, y-incr) ) //legaldirs |= 0x4; //left-up
16818 {
16819 //zprint2("Spawn adjustment: -x (%d), -y (%d)\n", incr, incr);
16820 x-=incr; y-=incr; break;
16821 }
16822 else if ( !m_walkflag_simple(x+incr, y-incr) ) //legaldirs |= 0x8; //right-up
16823 {
16824 //zprint2("Spawn adjustment: +x (%d), -y (%d)\n", incr, incr);
16825 x+=incr; y-=incr; break;
16826 }
16827 else if ( !m_walkflag_simple(x, y-incr) ) // legaldirs |= 0x10; //up
16828 {
16829 //zprint2("Spawn adjustment: -y (%d)\n", incr);
16830 y -= incr; break;
16831 }
16832 else if ( !m_walkflag_simple(x, y+incr) ) //legaldirs |= 0x20; //down
16833 {
16834 //zprint2("Spawn adjustment: +y (%d)\n", incr);
16835 y+=incr; break;
16836 }
16837 else if ( !m_walkflag_simple(x-incr, y+incr) ) //legaldirs |= 0x40; //left-down
16838 {
16839 //zprint2("Spawn adjustment: -x (%d), +y (%d)\n", incr, incr);
16840 x-=incr; y+=incr; break;
16841 }
16842 else if ( !m_walkflag_simple(x+incr, y+incr) ) //legaldirs |= 0x80; //right-down
16843 {
16844 //zprint2("Spawn adjustment: +x (%d), +y (%d)\n", incr, incr);
16845 x+=incr; y+=incr; break;
16846 }
16847 else continue;
16848
16849 }
16850
16851 }
16852
16853 dir=up;
16854 superman=1;
16855 fading=fade_invisible;
16856 hxofs=1000;
16857 segcnt=clk;
16858 clk=0;
16859 //set up move history
16860 for(int32_t i=0; i <= (1<<dmisc2); i++)
16861 prevState.push_back(std::pair<std::pair<zfix, zfix>, int32_t>(std::pair<zfix,zfix>(x,y), dir));
16862 }
16863
16864 bool eLanmola::animate(int32_t index)
16865 {
16866 if(switch_hooked) return enemy::animate(index);
16867 if(clk==0)
16868 {
16869 removearmos(x,y,ffcactivated);
16870 }
16871
16872 if(clk2)
16873 {
16874 if(--clk2 == 0)
16875 {
16876 if(!dmisc3) //This checks if "segments drop items" isn't true, because if they don't drop items, then only killing the whole thing drops an item.
16877 leave_item();
16878
16879 stop_bgsfx(index);
16880 return true;
16881 }
16882
16883 return false;
16884 }
16885
16886
16887 //this animation style plays ALL KINDS of havoc on the Lanmola segments, since it causes
16888 //the direction AND x,y position of the lanmola to vary in uncertain ways.
16889 //I've added a complete movement history to this enemy to compensate -DD
16890 constant_walk(rate,homing,spw_none);
16891 prevState.pop_front();
16892 prevState.push_front(std::pair<std::pair<zfix, zfix>, int32_t>(std::pair<zfix, zfix>(x,y), dir));
16893
16894 // This could cause a crash with Moldorms. I didn't see the same problem
16895 // with Lanmolas, but it looks like it ought to be possible, so here's
16896 // the same solution. - Saf
16897 if(index+segcnt>=guys.Count())
16898 segcnt=guys.Count()-index-1;
16899
16900 for(int32_t i=index+1; i<index+segcnt+1; i++)
16901 {
16902 enemy* segment=((enemy*)guys.spr(i));
16903
16904 // More validation in case segcnt is wrong
16905 if((segment->id&0xFFF)!=(id&0xFFF))
16906 {
16907 segcnt=i-index-1;
16908 break;
16909 }
16910
16911 segment->o_tile=o_tile;
16912 segment->parent_script_UID = this->script_UID;
16913 if((i==index+segcnt)&&(i!=index+1))
16914 {
16915 segment->dummy_int[1]=1; //tail
16916 }
16917 else
16918 {
16919 segment->dummy_int[1]=0;
16920 }
16921
16922 if(segment->hp <= 0)
16923 {
16924 for(int32_t j=i; j<index+segcnt; j++)
16925 {
16926 // Triple-check
16927 if((((enemy*)guys.spr(j+1))->id&0xFFF)!=(id&0xFFF))
16928 {
16929 segcnt=j-index+1; // Add 1 because of --segcnt below
16930 break;
16931 }
16932 zc_swap(((enemy*)guys.spr(j))->hp,((enemy*)guys.spr(j+1))->hp);
16933 zc_swap(((enemy*)guys.spr(j))->hclk,((enemy*)guys.spr(j+1))->hclk);
16934 }
16935
16936 ((enemy*)guys.spr(i))->hclk=33;
16937 --segcnt;
16938 --i; // Recheck the same index in case multiple segments died at once
16939 }
16940 }
16941
16942 if(segcnt==0)
16943 {
16944 clk2=19;
16945 x=guys.spr(index+1)->x;
16946 y=guys.spr(index+1)->y;
16947 setmapflag(mTMPNORET);
16948 }
16949
16950 //this enemy is invincible.. BUT scripts don't know that, and can "kill" it by setting the hp negative.
16951 //which is... disastrous.
16952 hp = 1;
16953 return enemy::animate(index);
16954 }
16955
16956 esLanmola::esLanmola(zfix X,zfix Y,int32_t Id,int32_t Clk) : eBaseLanmola(X,Y,Id,Clk)
16957 {
16958 if( !(editorflags & ENEMY_FLAG5) )
16959 {
16960 x=64;
16961 y=80;
16962 }
16963 int32_t incr = 16;
16964 //Don't spawn in pits.
16965 if ( m_walkflag_simple(x, y) )
16966 {
16967 //zprint2("Can't spawn here.\n");
16968 for ( ; incr < 240; incr += 16 )
16969 {
16970 //move if we spawn over a pit
16971 //check each direction
16972 if ( !m_walkflag_simple(x-incr, y) ) //legaldirs |= 0x1; //left
16973 {
16974 //zprint2("Spawn adjustment: -x (%d)\n", incr);
16975 x-=incr; break;
16976 }
16977 else if ( !m_walkflag_simple(x+incr, y) ) //legaldirs |= 0x2; //right
16978 {
16979 //zprint2("Spawn adjustment: +x (%d)\n", incr);
16980 x+=incr; break;
16981 }
16982 else if ( !m_walkflag_simple(x-incr, y-incr) ) //legaldirs |= 0x4; //left-up
16983 {
16984 //zprint2("Spawn adjustment: -x (%d), -y (%d)\n", incr, incr);
16985 x-=incr; y-=incr; break;
16986 }
16987 else if ( !m_walkflag_simple(x+incr, y-incr) ) //legaldirs |= 0x8; //right-up
16988 {
16989 //zprint2("Spawn adjustment: +x (%d), -y (%d)\n", incr, incr);
16990 x+=incr; y-=incr; break;
16991 }
16992 else if ( !m_walkflag_simple(x, y-incr) ) // legaldirs |= 0x10; //up
16993 {
16994 //zprint2("Spawn adjustment: -y (%d)\n", incr);
16995 y -= incr; break;
16996 }
16997 else if ( !m_walkflag_simple(x, y+incr) ) //legaldirs |= 0x20; //down
16998 {
16999 //zprint2("Spawn adjustment: +y (%d)\n", incr);
17000 y+=incr; break;
17001 }
17002 else if ( !m_walkflag_simple(x-incr, y+incr) ) //legaldirs |= 0x40; //left-down
17003 {
17004 //zprint2("Spawn adjustment: -x (%d), +y (%d)\n", incr, incr);
17005 x-=incr; y+=incr; break;
17006 }
17007 else if ( !m_walkflag_simple(x+incr, y+incr) ) //legaldirs |= 0x80; //right-down
17008 {
17009 //zprint2("Spawn adjustment: +x (%d), +y (%d)\n", incr, incr);
17010 x+=incr; y+=incr; break;
17011 }
17012 else continue;
17013
17014 }
17015
17016 }
17017
17018 hxofs=1000;
17019 hxsz=8;
17020 mainguy=false;
17021 count_enemy=(id<0x2000)?true:false;
17022
17023 //set up move history
17024 for(int32_t i=0; i <= (1<<dmisc2); i++)
17025 prevState.push_back(std::pair<std::pair<zfix, zfix>, int32_t>(std::pair<zfix,zfix>(x,y), dir));
17026
17027 bgsfx = -1;
17028 isCore = false;
17029 flags&=~guy_neverret;
17030 }
17031
17032 bool esLanmola::animate(int32_t index)
17033 {
17034 if(switch_hooked) return enemy::animate(index);
17035 // Shouldn't be possible, but who knows
17036 if(index==0)
17037 dying=true;
17038
17039 if(dying)
17040 {
17041 xofs=0;
17042
17043 if(!dmisc3)
17044 item_set=0;
17045
17046 return Dead(index);
17047 }
17048
17049 if(clk>=0)
17050 {
17051 hxofs=4;
17052
17053 if(!watch)
17054 {
17055 std::pair<std::pair<zfix, zfix>, int32_t> newstate = ((eBaseLanmola*)guys.spr(index-1))->prevState.front();
17056 prevState.pop_front();
17057 prevState.push_back(newstate);
17058 x = newstate.first.first;
17059 y = newstate.first.second;
17060 dir = newstate.second;
17061 }
17062 }
17063
17064 return enemy::animate(index);
17065 }
17066
17067 int32_t esLanmola::takehit(weapon *w)
17068 {
17069 if(enemy::takehit(w))
17070 return (w->id==wSBomb) ? 1 : 2; // force it to wait a frame before checking sword attacks again
17071
17072 return 0;
17073 }
17074
17075 void esLanmola::draw(BITMAP *dest)
17076 {
17077 tile=o_tile;
17078 int32_t fdiv = frate/4;
17079 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
17080
17081 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
17082 efrate:((clk>=(frate>>1))?1:0);
17083
17084 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17085 {
17086 if(id>=0x2000)
17087 {
17088 tile+=20;
17089
17090 if(dummy_int[1]==1)
17091 {
17092 tile+=20;
17093 }
17094 }
17095
17096 switch(dir)
17097 {
17098 case up:
17099 flip=0;
17100 break;
17101
17102 case down:
17103 flip=0;
17104 tile+=4;
17105 break;
17106
17107 case left:
17108 flip=0;
17109 tile+=8;
17110 break;
17111
17112 case right:
17113 flip=0;
17114 tile+=12;
17115 break;
17116 }
17117
17118 tile+=f2;
17119 }
17120 else
17121 {
17122 if(id>=0x2000)
17123 {
17124 tile+=1;
17125 }
17126 }
17127
17128 if(clk>=0)
17129 enemy::draw(dest);
17130 }
17131
17132 eManhandla::eManhandla(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,0)
17133 {
17134 //these are here to bypass compiler warnings about unused arguments
17135 Clk=Clk;
17136 superman=1;
17137 dir=(zc_oldrand()&7)+8;
17138 armcnt=dmisc2?8:4;//((id==eMANHAN)?4:8);
17139
17140 for(int32_t i=0; i<armcnt; i++)
17141 arm[i]=i;
17142
17143 fading=fade_blue_poof;
17144 //nets+4680;
17145 adjusted=false;
17146 SIZEflags = d->SIZEflags; //Probably will be buggy. -Z 12 AUG 2020
17147 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
17148 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
17149 // al_trace("Enemy txsz:%i\n", txsz);
17150 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
17151 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
17152 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
17153 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
17154 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
17155 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
17156 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
17157 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
17158 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
17159 {
17160 yofs = d->yofs+(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
17161 }
17162
17163 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
17164 }
17165
17166 bool eManhandla::animate(int32_t index)
17167 {
17168 if(switch_hooked) return enemy::animate(index);
17169 if(dying)
17170 return Dead(index);
17171
17172 if(clk==0)
17173 {
17174 removearmos(x,y,ffcactivated);
17175 }
17176
17177
17178 // check arm status, move dead ones to end of group
17179 for(int32_t i=0; i<armcnt; i++)
17180 {
17181 enemy* cur_arm = ((enemy*)guys.spr(index+i+1));
17182 if(!cur_arm || cur_arm->dying)
17183 {
17184 for(int32_t j=i; j<armcnt-1; j++)
17185 {
17186 zc_swap(arm[j],arm[j+1]);
17187 guys.swap(index+j+1,index+j+2);
17188 }
17189 if((editorflags & ENEMY_FLAG6)) //They only did this in 2.10
17190 {
17191 leave_item();
17192 }
17193 --armcnt;
17194 --i;
17195 continue;
17196 }
17197 if(!adjusted)
17198 {
17199 if(!dmisc2)
17200 {
17201 cur_arm->o_tile=o_tile+40;
17202 cur_arm->parent_script_UID = this->script_UID;
17203 }
17204 else
17205 {
17206 cur_arm->o_tile=o_tile+160;
17207 cur_arm->parent_script_UID = this->script_UID;
17208 }
17209 }
17210 }
17211
17212 adjusted=true;
17213
17214 // move or die
17215 if(armcnt==0)
17216 hp=0;
17217 else
17218 {
17219 // Speed starts at 0.5, and increases by 0.5 for each head lost. Max speed is 4.5.
17220 step=zc_min(zfix(4.5),(((!dmisc2)?4:8)-int64_t(armcnt))*0.5+zslongToFix(dstep*100));
17221 int32_t dx1=0, dy1=-8, dx2=15, dy2=15;
17222
17223 if(!dmisc2)
17224 {
17225 for(int32_t i=0; i<armcnt; i++)
17226 {
17227 switch(arm[i])
17228 {
17229 case 0:
17230 dy1=-24;
17231 break;
17232
17233 case 1:
17234 dy2=31;
17235 break;
17236
17237 case 2:
17238 dx1=-16;
17239 break;
17240
17241 case 3:
17242 dx2=31;
17243 break;
17244 }
17245 }
17246 }
17247 else
17248 {
17249 dx1=-8, dy1=-16, dx2=23, dy2=23;
17250
17251 for(int32_t i=0; i<armcnt; i++)
17252 {
17253 switch(arm[i]&3)
17254 {
17255 case 0:
17256 dy1=-32;
17257 break;
17258
17259 case 1:
17260 dy2=39;
17261 break;
17262
17263 case 2:
17264 dx1=-24;
17265 break;
17266
17267 case 3:
17268 dx2=39;
17269 break;
17270 }
17271 }
17272 }
17273
17274 variable_walk_8(rate,homing,hrate,spw_floater,dx1,dy1,dx2,dy2);
17275
17276 for(int32_t i=0; i<armcnt; i++)
17277 {
17278 zfix dx=(zfix)0,dy=(zfix)0;
17279
17280 if(!dmisc2)
17281 {
17282 switch(arm[i])
17283 {
17284 case 0:
17285 dy=-16;
17286 break;
17287
17288 case 1:
17289 dy=16;
17290 break;
17291
17292 case 2:
17293 dx=-16;
17294 break;
17295
17296 case 3:
17297 dx=16;
17298 break;
17299 }
17300 }
17301 else
17302 {
17303 switch(arm[i])
17304 {
17305 case 0:
17306 dy=-24;
17307 dx=-8;
17308 break;
17309
17310 case 1:
17311 dy=24;
17312 dx=8;
17313 break;
17314
17315 case 2:
17316 dx=-24;
17317 dy=8;
17318 break;
17319
17320 case 3:
17321 dx=24;
17322 dy=-8;
17323 break;
17324
17325 case 4:
17326 dy=-24;
17327 dx=8;
17328 break;
17329
17330 case 5:
17331 dy=24;
17332 dx=-8;
17333 break;
17334
17335 case 6:
17336 dx=-24;
17337 dy=-8;
17338 break;
17339
17340 case 7:
17341 dx=24;
17342 dy=8;
17343 break;
17344 }
17345 }
17346
17347 guys.spr(index+i+1)->x = x+dx;
17348 guys.spr(index+i+1)->y = y+dy;
17349 }
17350 }
17351
17352 return enemy::animate(index);
17353 }
17354
17355
17356 int32_t eManhandla::takehit(weapon *w)
17357 {
17358 int32_t wpnId = w->id;
17359
17360 if(dying)
17361 return 0;
17362
17363 switch(wpnId)
17364 {
17365 case wBomb:
17366 case wSBomb:
17367 case wSword:
17368 case wHammer:
17369 case wWand:
17370 if (get_bit(quest_rules, qr_MANHANDLA_BLOCK_SFX)) sfx(WAV_EHIT,pan(int32_t(x)));
17371
17372 case wLitBomb:
17373 case wLitSBomb:
17374 case wBait:
17375 case wWhistle:
17376 case wFire:
17377 case wWind:
17378 case wSSparkle:
17379 case wFSparkle:
17380 case wPhantom:
17381 return 0;
17382
17383 case wHookshot:
17384 case wBrang:
17385 sfx(WAV_CHINK,pan(int32_t(x)));
17386 break;
17387
17388 default:
17389 if (get_bit(quest_rules, qr_MANHANDLA_BLOCK_SFX)) sfx(WAV_EHIT,pan(int32_t(x)));
17390 else sfx(WAV_CHINK,pan(int32_t(x)));
17391
17392 }
17393
17394 return 1;
17395 }
17396
17397 void eManhandla::draw(BITMAP *dest)
17398 {
17399 tile=o_tile;
17400 int32_t fdiv = frate/4;
17401 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
17402
17403 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
17404 efrate:((clk>=(frate>>1))?1:0);
17405
17406 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17407 {
17408 if(!dmisc2)
17409 {
17410 switch(dir-8) //directions get screwed up after 8. *shrug*
17411 {
17412 case up: //u
17413 flip=0;
17414 break;
17415
17416 case l_up: //d
17417 flip=0;
17418 tile+=4;
17419 break;
17420
17421 case l_down: //l
17422 flip=0;
17423 tile+=8;
17424 break;
17425
17426 case left: //r
17427 flip=0;
17428 tile+=12;
17429 break;
17430
17431 case r_down: //ul
17432 flip=0;
17433 tile+=20;
17434 break;
17435
17436 case down: //ur
17437 flip=0;
17438 tile+=24;
17439 break;
17440
17441 case r_up: //dl
17442 flip=0;
17443 tile+=28;
17444 break;
17445
17446 case right: //dr
17447 flip=0;
17448 tile+=32;
17449 break;
17450 }
17451
17452 tile+=f2;
17453 enemy::draw(dest);
17454 } //manhandla 2, big body
17455 else
17456 {
17457
17458 switch(dir-8) //directions get screwed up after 8. *shrug*
17459 {
17460 case up: //u
17461 flip=0;
17462 break;
17463
17464 case l_up: //d
17465 flip=0;
17466 tile+=8;
17467 break;
17468
17469 case l_down: //l
17470 flip=0;
17471 tile+=40;
17472 break;
17473
17474 case left: //r
17475 flip=0;
17476 tile+=48;
17477 break;
17478
17479 case r_down: //ul
17480 flip=0;
17481 tile+=80;
17482 break;
17483
17484 case down: //ur
17485 flip=0;
17486 tile+=88;
17487 break;
17488
17489 case r_up: //dl
17490 flip=0;
17491 tile+=120;
17492 break;
17493
17494 case right: //dr
17495 flip=0;
17496 tile+=128;
17497 break;
17498 }
17499
17500 tile+=(f2*2);
17501 xofs-=8;
17502 yofs-=8;
17503 drawblock(dest,15);
17504 xofs+=8;
17505 yofs+=8;
17506 }
17507 }
17508 else
17509 {
17510 if(!dmisc2)
17511 {
17512 enemy::draw(dest);
17513 }
17514 else
17515 {
17516 xofs-=8;
17517 yofs-=8;
17518 enemy::draw(dest);
17519 xofs+=16;
17520 enemy::draw(dest);
17521 yofs+=16;
17522 enemy::draw(dest);
17523 xofs-=16;
17524 enemy::draw(dest);
17525 xofs+=8;
17526 yofs-=8;
17527 }
17528 }
17529 }
17530
17531 esManhandla::esManhandla(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
17532 {
17533 id=misc=clk;
17534 dir = clk & 3;
17535 clk=0;
17536 mainguy=count_enemy=false;
17537 dummy_bool[0]=false;
17538 item_set=0;
17539 bgsfx=-1;
17540 deadsfx = WAV_EDEAD;
17541 flags &= (~guy_neverret);
17542 isCore = false;
17543 //Probably will be buggy. -Z 12 AUG 2020
17544 SIZEflags = d->SIZEflags;
17545 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
17546 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
17547 // al_trace("Enemy txsz:%i\n", txsz);
17548 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
17549 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
17550 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
17551 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
17552 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
17553 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
17554 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
17555 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
17556 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
17557 {
17558 yofs = d->yofs+(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
17559 }
17560
17561 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
17562 }
17563
17564 bool esManhandla::animate(int32_t index)
17565 {
17566 if(switch_hooked) return enemy::animate(index);
17567 if(dying)
17568 return Dead(index);
17569
17570 if(clk==0)
17571 {
17572 removearmos(x,y,ffcactivated);
17573 }
17574
17575 if(--clk2<=0)
17576 {
17577 clk2=unsigned(zc_oldrand())%5+5;
17578 clk3^=1;
17579 }
17580
17581 if(!(zc_oldrand()&127))
17582 {
17583 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
17584 sfx(wpnsfx(wpn),pan(int32_t(x)));
17585 }
17586
17587 return enemy::animate(index);
17588 }
17589
17590 void esManhandla::draw(BITMAP *dest)
17591 {
17592 tile=o_tile;
17593 int32_t fdiv = frate/4;
17594 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
17595 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
17596 efrate:((clk>=(frate>>1))?1:0);
17597
17598 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17599 {
17600 switch(misc&3)
17601 {
17602 case up:
17603 break;
17604
17605 case down:
17606 tile+=4;
17607 break;
17608
17609 case left:
17610 tile+=8;
17611 break;
17612
17613 case right:
17614 tile+=12;
17615 break;
17616 }
17617
17618 tile+=f2;
17619 }
17620 else
17621 {
17622 switch(misc&3)
17623 {
17624 case down:
17625 flip=2;
17626
17627 [[fallthrough]];
17628 case up:
17629 tile=(clk3)?188:189;
17630 break;
17631
17632 case right:
17633 flip=1;
17634 [[fallthrough]];
17635
17636 case left:
17637 tile=(clk3)?186:187;
17638 break;
17639 }
17640 }
17641
17642 enemy::draw(dest);
17643 }
17644
17645 eGleeok::eGleeok(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk) //enemy((zfix)120,(zfix)48,Id,Clk)
17646 {
17647 if ( !(editorflags & ENEMY_FLAG5) )
17648 {
17649 x = 120;
17650 y = 48;
17651 }
17652 else
17653 {
17654 if ( !(editorflags & ENEMY_FLAG6) )
17655 {
17656 x = X; y = Y;
17657 }
17658 else
17659 {
17660 x = X+8; y = Y;
17661 }
17662 }
17663 hzsz = 32; // can't be jumped.
17664 flameclk=0;
17665 misc=clk; // total head count
17666 clk3=clk; // live head count
17667 clk=0;
17668 clk2=60; // fire ball clock
17669 // hp=(guysbuf[eGLEEOK2+(misc-2)].misc2)*(misc-1)*game->get_hero_dmgmult()+guysbuf[eGLEEOK2+(misc-2)].hp;
17670 hp=(guysbuf[id&0xFFF].misc2)*(misc-1)*game->get_hero_dmgmult()+guysbuf[id&0xFFF].hp;
17671 dir = down;
17672 hxofs=4;
17673 hxsz=8;
17674 // frate=17*4;
17675 fading=fade_blue_poof;
17676 //nets+5420;
17677 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17678 {
17679 /*
17680 necktile=o_tile+8;
17681 if (dmisc3)
17682 {
17683 necktile+=8;
17684 }
17685 */
17686 necktile=o_tile+dmisc6;
17687 }
17688 else
17689 {
17690 necktile=s_tile;
17691 }
17692 }
17693
17694 bool eGleeok::animate(int32_t index)
17695 {
17696 if(switch_hooked) return enemy::animate(index);
17697 if(dying)
17698 return Dead(index);
17699
17700 if(clk==0)
17701 {
17702 removearmos(x,y,ffcactivated);
17703 }
17704
17705 // Check if a head was killed somehow...
17706 if(index+1+clk3>=guys.Count())
17707 clk3=guys.Count()-index-1;
17708 if(index+1+misc>=guys.Count())
17709 misc=guys.Count()-index-1;
17710
17711 //fix for the "kill all enemies" item
17712 if(hp==-1000)
17713 {
17714 for(int32_t i=0; i<clk3; ++i)
17715 {
17716 // I haven't seen this fail, but it seems like it ought to be
17717 // possible, so I'm checking for it. - Saf
17718 if((((enemy*)guys.spr(index+i+1))->id&0xFFF)!=(id&0xFFF))
17719 break;
17720 ((enemy*)guys.spr(index+i+1))->hp=1; // re-animate each head,
17721 ((enemy*)guys.spr(index+i+1))->misc = -1; // disconnect it,
17722 ((enemy*)guys.spr(index+i+1))->animate(index+i+1); // let it animate one frame,
17723 ((enemy*)guys.spr(index+i+1))->hp=-1000; // and kill it for good
17724 }
17725
17726 clk3=0;
17727
17728 for(int32_t i=0; i<misc; i++)
17729 {
17730 if((((enemy*)guys.spr(index+i+1))->id&0xFFF)!=(id&0xFFF))
17731 break;
17732 ((enemy*)guys.spr(index+i+1))->misc = -2; // give the signal to disappear
17733 }
17734 }
17735
17736 for(int32_t i=0; i<clk3; i++)
17737 {
17738 enemy *head = ((enemy*)guys.spr(index+i+1));
17739 head->dummy_int[1]=necktile;
17740 head->parent_script_UID = this->script_UID;
17741
17742 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17743 {
17744 head->dummy_int[2]=o_tile+dmisc8; //connected head tile
17745 head->dummy_int[3]=o_tile+dmisc9; //flying head tile
17746 }
17747 else
17748 {
17749 head->dummy_int[2]=necktile+1; //connected head tile
17750 head->dummy_int[3]=necktile+2; //flying head tile
17751 }
17752
17753 head->dmisc5=dmisc5; //neck segments
17754
17755 /*
17756 if (dmisc3)
17757 {
17758 head->dummy_bool[0]=true;
17759 }
17760 */
17761 if(head->hclk)
17762 {
17763 if(hclk==0)
17764 {
17765 hp -= 1000 - head->hp;
17766 hclk = 33;
17767
17768 if(hitsfx>0) sfx(hitsfx,pan(int32_t(head->x)));
17769
17770 sfx(WAV_EHIT,pan(int32_t(head->x)));
17771 }
17772
17773 head->hclk = 0;
17774 }
17775
17776 // Must be set in case of naughty ZScripts
17777 head->hp = 1000;
17778 }
17779
17780 if(hp<=(guysbuf[id&0xFFF].misc2)*(clk3-1)*game->get_hero_dmgmult())
17781 {
17782 ((enemy*)guys.spr(index+clk3))->misc = -1; // give signal to fly off
17783 hp=(guysbuf[id&0xFFF].misc2)*(--clk3)*game->get_hero_dmgmult();
17784 }
17785
17786 if(!dmisc3)
17787 {
17788 if(++clk2>72 && !(zc_oldrand()&3))
17789 {
17790 int32_t i=zc_oldrand()%misc;
17791 enemy *head = ((enemy*)guys.spr(index+i+1));
17792 addEwpn(head->x,head->y,head->z,wpn,3,wdp,dir,getUID(), 0, head->fakez);
17793 sfx(wpnsfx(wpn),pan(int32_t(x)));
17794 clk2=0;
17795 }
17796 }
17797 else
17798 {
17799 if(++clk2>100 && !(zc_oldrand()&3))
17800 {
17801 enemy *head = ((enemy*)guys.spr(zc_oldrand()%misc+index+1));
17802 head->timer=zc_oldrand()%50+50;
17803 clk2=0;
17804 }
17805 }
17806
17807 if((hp<=0 && !immortal))
17808 {
17809 for(int32_t i=0; i<misc; i++)
17810 ((enemy*)guys.spr(index+i+1))->misc = -2; // give the signal to disappear
17811
17812 if(flags&guy_neverret) never_return(index);
17813 }
17814
17815 return enemy::animate(index);
17816 }
17817
17818 int32_t eGleeok::takehit(weapon*)
17819 {
17820 return 0;
17821 }
17822
17823 void eGleeok::draw(BITMAP *dest)
17824 {
17825 tile=o_tile;
17826
17827 if(dying)
17828 {
17829 enemy::draw(dest);
17830 return;
17831 }
17832
17833 int32_t f=clk/17;
17834
17835 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17836 {
17837 // body
17838 xofs=-8;
17839 yofs=32;
17840
17841 switch(f)
17842
17843 {
17844 case 0:
17845 tile+=0;
17846 break;
17847
17848 case 1:
17849 tile+=2;
17850 break;
17851
17852 case 2:
17853 tile+=4;
17854 break;
17855
17856 default:
17857 tile+=6;
17858 break;
17859 }
17860 }
17861 else
17862 {
17863 // body
17864 xofs=-8;
17865 yofs=32;
17866
17867 switch(f)
17868 {
17869 case 0:
17870 tile+=0;
17871 break;
17872
17873 case 2:
17874 tile+=4;
17875 break;
17876
17877 default:
17878 tile+=2;
17879 break;
17880 }
17881 }
17882
17883 enemy::drawblock(dest,15);
17884 }
17885
17886 void eGleeok::draw2(BITMAP *dest)
17887 {
17888 // the neck stub
17889 tile=necktile;
17890 xofs=0;
17891 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
17892
17893 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17894 {
17895 tile+=((clk&24)>>3);
17896 }
17897
17898 if(hp > 0 && !dont_draw())
17899 {
17900 if((tmpscr->flags3&fINVISROOM)&& !(current_item(itype_amulet)))
17901 sprite::drawcloaked(dest);
17902 else
17903 sprite::draw(dest);
17904 }
17905 }
17906
17907 esGleeok::esGleeok(zfix X,zfix Y,int32_t Id,int32_t Clk, sprite * prnt) : enemy(X,Y,Id,Clk), parent(prnt)
17908 {
17909 xoffset=0;
17910 yoffset=(zfix)((dmisc5*4+2));
17911 // dummy_bool[0]=false;
17912 timer=0;
17913 /* fixing */
17914 hp=1000;
17915 step=1;
17916 item_set=0;
17917 //x=120; y=70;
17918 x = xoffset+parent->x;
17919 y = yoffset+parent->y;
17920 hxofs=4;
17921 hxsz=8;
17922 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
17923 clk2=clk; // how int32_t to wait before moving first time
17924 clk=0;
17925 mainguy=count_enemy=false;
17926 dir=zc_oldrand();
17927 clk3=((dir&2)>>1)+2; // left or right
17928 dir&=1; // up or down
17929 dmisc5=vbound(dmisc5,1,255);
17930 isCore = false;
17931 parentCore = parent->getUID();
17932 for(int32_t i=0; i<dmisc5; i++)
17933 {
17934 nxoffset[i] = 0;
17935 nyoffset[i] = 0;
17936 nx[i] = ((((i*(int32_t)x) + (dmisc5-i)*((int32_t)parent->x))) /dmisc5);
17937 ny[i] = ((((i*(int32_t)y) + (dmisc5-i)*((int32_t)parent->y))) /dmisc5);
17938 }
17939
17940 necktile=0;
17941 //TODO compatibility? -DD
17942 /*
17943 for(int32_t i=0; i<4; i++)
17944 {
17945 nx[i]=124;
17946 ny[i]=i*6+48;
17947 }*/
17948 bgsfx=-1;
17949 //no need for deadsfx
17950 }
17951
17952 bool esGleeok::animate(int32_t index)
17953 {
17954 if(switch_hooked) return enemy::animate(index);
17955 // don't call removearmos() - it's a segment.
17956
17957 dmisc5=vbound(dmisc5,1,255);
17958
17959 if(misc == 0)
17960 {
17961 x = (xoffset+parent->x);
17962 y = (yoffset+parent->y);
17963
17964 for(int32_t i=0; i<dmisc5; i++)
17965 {
17966 nx[i] = ((((i*(int32_t)x) + (dmisc5-i)*((int32_t)parent->x))) /dmisc5) + 3 + nxoffset[i];
17967 ny[i] = ((((i*(int32_t)y) + (dmisc5-i)*((int32_t)parent->y))) /dmisc5) + nyoffset[i];
17968 }
17969 }
17970
17971 // set up the head tiles
17972 // headtile=nets+5588; //5580, actually. must adjust for direction later on
17973 /*
17974 if (dummy_bool[0]) //if this is a flame gleeok
17975 {
17976 headtile+=180;
17977 }
17978 */
17979 headtile=dummy_int[2]; //5580, actually. must adjust for direction later on
17980 flyingheadtile=dummy_int[3];
17981
17982 // set up the neck tiles
17983 necktile=dummy_int[1];
17984
17985 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17986 {
17987 necktile+=((clk&24)>>3);
17988 }
17989
17990 /*
17991 else
17992 {
17993 necktile=145;
17994 }
17995 */
17996 // ?((dummy_bool[0])?(nets+4052+(16+((clk&24)>>3))):(nets+4040+(8+((clk&24)>>3)))):145)
17997
17998 switch(misc)
17999 {
18000 case 0: // live head
18001 // set up the attached head tiles
18002 tile=headtile;
18003
18004 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18005 {
18006 tile+=((clk&24)>>3);
18007 /*
18008 if (dummy_bool[0]) {
18009 tile+=1561;
18010 }
18011 */
18012 }
18013
18014 /*
18015 else
18016 {
18017 tile=146;
18018 }
18019 */
18020 if(++clk2>=0 && !(clk2&3))
18021 {
18022 if(y<= (int32_t)parent->y + 8) dir=down;
18023
18024 if(y>= (int32_t)parent->y + dmisc5*8) dir = up;
18025
18026 if(y<= (int32_t)parent->y + 10 && !(zc_oldrand()&31))
18027 {
18028 dir^=1;
18029 }
18030
18031 zfix tempx = x;
18032 zfix tempy = y;
18033
18034 sprite::move(step);
18035 xoffset += (x-tempx);
18036 yoffset += (y-tempy);
18037
18038 if(clk2>=4)
18039 {
18040 clk3^=1;
18041 clk2=-4;
18042 }
18043 else
18044 {
18045 if(x <= (int32_t)parent->x-(dmisc5*6))
18046 {
18047 clk3=right;
18048 }
18049
18050 if(x >= (int32_t)parent->x+(dmisc5*6))
18051 {
18052 clk3=left;
18053 }
18054
18055 if(y <= (int32_t)parent->y+(dmisc5*6) && !(zc_oldrand()&15))
18056 {
18057 clk3^=1; // x jig
18058 }
18059 else
18060 {
18061 if(y<=(int32_t)parent->y+(dmisc5*4) && !(zc_oldrand()&31))
18062 {
18063 clk3^=1; // x switch back
18064 }
18065
18066 clk2=-4;
18067 }
18068 }
18069
18070 zc_swap(dir,clk3);
18071 tempx = x;
18072 tempy = y;
18073 sprite::move(step);
18074 xoffset += (x-tempx);
18075 yoffset += (y-tempy);
18076 zc_swap(dir,clk3);
18077
18078 for(int32_t i=1; i<dmisc5; i++)
18079 {
18080 nxoffset[i] = (zc_oldrand()%3);
18081 nyoffset[i] = (zc_oldrand()%3);
18082 }
18083 }
18084
18085 break;
18086
18087 case 1: // flying head
18088 if(clk>=0)
18089
18090 {
18091 variable_walk_8(rate,homing,hrate,spw_floater);
18092 }
18093
18094 break;
18095
18096 // the following are messages sent from the main guy...
18097 case -1: // got chopped off
18098 {
18099 misc=1;
18100 superman=1;
18101 hxofs=xofs=0;
18102 hxsz=16;
18103 cs=8;
18104 clk=-24;
18105 clk2=40;
18106 dir=(zc_oldrand()&7)+8;
18107 step=8.0/9.0;
18108 }
18109 break;
18110
18111 case -2: // the big guy is dead
18112 return true;
18113 }
18114
18115 if(timer)
18116 {
18117 if(!(timer%8))
18118 {
18119 FireBreath(true);
18120 }
18121
18122 --timer;
18123 }
18124
18125 return enemy::animate(index);
18126 }
18127
18128 int32_t esGleeok::takehit(weapon *w)
18129 {
18130 if ((editorflags & ENEMY_FLAG7) && misc == 1)
18131 {
18132 int32_t wpnId = w->id;
18133
18134 if(dying)
18135 return 0;
18136
18137 switch(wpnId)
18138 {
18139 case wLitBomb:
18140 case wLitSBomb:
18141 case wBait:
18142 case wWhistle:
18143 case wFire:
18144 case wWind:
18145 case wSSparkle:
18146 case wFSparkle:
18147 case wPhantom:
18148 return 0;
18149
18150 case wHookshot:
18151 case wBrang:
18152 case wBeam:
18153 case wArrow:
18154 case wMagic:
18155 case wBomb:
18156 case wSBomb:
18157 sfx(WAV_CHINK,pan(int32_t(x)));
18158 break;
18159 default:
18160 break;
18161 }
18162
18163 return 1;
18164 }
18165 else
18166 {
18167 int32_t ret = enemy::takehit(w);
18168
18169 if(ret==-1)
18170 return 2; // force it to wait a frame before checking sword attacks again
18171
18172 return ret;
18173 }
18174 }
18175
18176 void esGleeok::draw(BITMAP *dest)
18177 {
18178 dmisc5=vbound(dmisc5,1,255);
18179
18180 switch(misc)
18181 {
18182 case 0: //neck
18183 if(!dont_draw())
18184 {
18185 for(int32_t i=1; i<dmisc5; i++) //draw the neck
18186 {
18187 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18188 {
18189 if((tmpscr->flags3&fINVISROOM)&& !(current_item(itype_amulet)))
18190 overtilecloaked16(dest,necktile+(i*dmisc7),nx[i]-4,ny[i]+playing_field_offset,0);
18191 else
18192 overtile16(dest,necktile+(i*dmisc7),nx[i]-4,ny[i]+playing_field_offset,cs,0);
18193 }
18194 else
18195 {
18196 if((tmpscr->flags3&fINVISROOM)&& !(current_item(itype_amulet)))
18197 overtilecloaked16(dest,necktile,nx[i]-4,ny[i]+playing_field_offset,0);
18198 else
18199 overtile16(dest,necktile,nx[i]-4,ny[i]+playing_field_offset,cs,0);
18200 }
18201 }
18202 }
18203
18204 break;
18205
18206 case 1: //flying head
18207 tile=flyingheadtile;
18208
18209 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18210 {
18211 tile+=((clk&24)>>3);
18212 break;
18213 }
18214
18215 /*
18216 else
18217 {
18218 tile=(clk&1)?147:148;
18219 break;
18220 }
18221 */
18222 }
18223 }
18224
18225 void esGleeok::draw2(BITMAP *dest)
18226 {
18227 enemy::draw(dest);
18228 }
18229
18230 ePatra::ePatra(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)// enemy((zfix)128,(zfix)48,Id,Clk)
18231 {
18232 if ( !(editorflags & ENEMY_FLAG5) )
18233 {
18234 x = 128;
18235 y = 48;
18236 }
18237 else { x = X; y = Y; }
18238 adjusted=false;
18239 dir=(zc_oldrand()&7)+8;
18240 //step=0.25;
18241 flycnt=dmisc1;
18242 flycnt2=dmisc2;
18243 loopcnt=0;
18244 clk4 = 0;
18245 clk5 = 0;
18246 clk6 = 0;
18247 clk7 = 0;
18248 if(dmisc6<int16_t(1))dmisc6=1; // ratio cannot be 0!
18249 SIZEflags = d->SIZEflags;
18250 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
18251 else if (dmisc10 == 1) { txsz = 2; extend = 3; }
18252 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
18253 // al_trace("Enemy txsz:%i\n", txsz);
18254 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = tysz; if ( tysz > 1 ) extend = 3; }
18255 else if (dmisc10 == 1) { tysz = 2; extend = 3; }
18256 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = hxsz;
18257 else if (dmisc10 == 1) hxsz = 32;
18258 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = hysz;
18259 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = hzsz;
18260 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = hxofs;
18261 else if (dmisc10 == 1) hxofs = -8;
18262 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = hyofs;
18263 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
18264 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)xofs;
18265 else if (dmisc10 == 1) xofs = -8;
18266 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
18267 {
18268 yofs = (int32_t)yofs; //This seems to be setting to +48 or something with any value set?! -Z
18269 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
18270 }
18271 else if (dmisc10 == 1) yofs = (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)-8;
18272 if (editorflags & ENEMY_FLAG8) misc = 1;
18273
18274 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
18275
18276 if (dmisc29 == 0)
18277 {
18278 if(!dmisc4)
18279 {
18280 if (dmisc10) dmisc29 = (90 / 3);
18281 else dmisc29 = (84 / 3);
18282 }
18283 else
18284 {
18285 if (dmisc10) dmisc29 = (90 / 2);
18286 else dmisc29 = (84 / 2);
18287 }
18288 }
18289 if (dmisc30 == 0)
18290 {
18291 if(!dmisc4)
18292 {
18293 if (dmisc10) dmisc30 = (90 / 3)*0.5;
18294 else dmisc30 = (84 / 3)*0.5;
18295 }
18296 else
18297 {
18298 if (dmisc10) dmisc30 = (90 / 2)*0.5;
18299 else dmisc30 = (84 / 2)*0.5;
18300 }
18301 }
18302 if (dmisc31 == 0)
18303 {
18304 if(!dmisc4)
18305 {
18306 if (dmisc10) dmisc31 = (90 / 3)*2;
18307 else dmisc31 = (84 / 3)*2;
18308 }
18309 else
18310 {
18311 if (dmisc10) dmisc31 = (90 / 2)*0.5;
18312 else dmisc31 = (84 / 2)*0.5;
18313 }
18314 }
18315 if (dmisc32 == 0)
18316 {
18317 if(!dmisc4)
18318 {
18319 if (dmisc10) dmisc32 = (90 / 3);
18320 else dmisc32 = (84 / 3);
18321 }
18322 else
18323 {
18324 if (dmisc10) dmisc32 = (90 / 2)*0.25;
18325 else dmisc32 = (84 / 2)*0.25;
18326 }
18327 }
18328 }
18329
18330 bool ePatra::animate(int32_t index)
18331 {
18332 if(switch_hooked) return enemy::animate(index);
18333 if(dying)
18334 {
18335 for(int32_t i=index+1; i<index+flycnt+flycnt2+1; i++)
18336 {
18337 ((enemy*)guys.spr(i))->hp = -1000;
18338 }
18339
18340 return Dead(index);
18341 }
18342
18343 double basesize = 84;
18344 if (dmisc10) basesize = 90;
18345 double halfsize = basesize / 2;
18346 double quartersize = halfsize / 2;
18347 double twothirdsize = (basesize / 3)*2;
18348 double onethirdsize = (basesize / 3);
18349
18350
18351 if(clk==0)
18352 {
18353 removearmos(x,y,ffcactivated);
18354 }
18355
18356 if ((clk4 <=0 || clk4%2) && (clk7 <= 0 || clk6 <= -16))
18357 {
18358 if (!dmisc22 || loopcnt == 0 || (dmisc22 == 1 && loopcnt < 0)) variable_walk_8(rate,homing,hrate,spw_floater);
18359 if (loopcnt < 0) ++clk2;
18360 if(++clk2>basesize)
18361 {
18362 clk2=0;
18363 if ((!dmisc26 || (dmisc26 == 1 && flycnt) || (dmisc26 == 2 && !flycnt)) && (!(editorflags & ENEMY_FLAG10) || flycnt || flycnt2))
18364 {
18365 if(loopcnt > 0)
18366 --loopcnt;
18367 else if (loopcnt == 0)
18368 {
18369 if((misc%dmisc6)==0)
18370 {
18371 if (dmisc21 > 0) loopcnt=-dmisc21;
18372 else loopcnt=dmisc7;
18373 }
18374 }
18375 else if (loopcnt == -1) loopcnt=dmisc7;
18376 else ++loopcnt;
18377
18378 if (!(editorflags & ENEMY_FLAG9) || loopcnt == 0) ++misc;
18379 }
18380 else
18381 {
18382 loopcnt = 0;
18383 misc = 1;
18384 }
18385 }
18386 }
18387 if (clk4 > 0) --clk4;
18388
18389 double size=1;
18390
18391 if (clk6 < 0)
18392 {
18393 if (dmisc5 == 1 || dmisc5 == 3)
18394 {
18395 if (get_bit(quest_rules,qr_NEWENEMYTILES))
18396 {
18397 if (clk7 <= 0 || clk6 != -16) ++clk6;
18398 if (clk6 == 0) o_tile=d->e_tile;
18399 else
18400 {
18401 if (clk6 >= -16) o_tile=d->e_tile + (IsBigAnim() ? 320 : 80);
18402 else o_tile=d->e_tile + (IsBigAnim() ? 160 : 40);
18403 }
18404 }
18405 else clk6 = 0;
18406 }
18407 }
18408 else if (dmisc19) ++clk6;
18409 if (clk5 < 0) ++clk5;
18410 else if (dmisc19) ++clk5;
18411
18412 if (clk7 > 0 && clk6 >= -16) --clk7;
18413 if (clk6 > 0) clk7 = 0;
18414
18415 for(int32_t i=index+1; i<index+flycnt+1; i++)
18416 {
18417 //outside ring
18418 if(!adjusted)
18419 {
18420 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18421 {
18422 ((enemy*)guys.spr(i))->o_tile=d->e_tile+dmisc8;
18423 enemy *s = ((enemy*)guys.spr(i));
18424 s->parent_script_UID = this->script_UID;
18425 }
18426 else
18427 {
18428 ((enemy*)guys.spr(i))->o_tile=o_tile+1;
18429 enemy *s = ((enemy*)guys.spr(i));
18430 s->parent_script_UID = this->script_UID;
18431 }
18432
18433 ((enemy*)guys.spr(i))->cs=dmisc9;
18434 ((enemy*)guys.spr(i))->hp=dmisc3;
18435 }
18436
18437 if(((enemy*)guys.spr(i))->hp <= 0)
18438 {
18439 for(int32_t j=i; j<index+flycnt+flycnt2; j++)
18440 {
18441 guys.swap(j,j+1);
18442 }
18443
18444 if (--flycnt == 0 && dmisc23 != 0) step += zslongToFix(dmisc23*100);
18445 }
18446 else
18447 {
18448 int32_t pos2 = ((enemy*)guys.spr(i))->misc;
18449 double a2 = (clk2-pos2*(double)basesize/(dmisc1 == 0 ? 1 : dmisc1))*PI/halfsize;
18450
18451 if(!dmisc4) //Big Ring
18452 {
18453 //maybe playing_field_offset here?
18454 if(loopcnt>0)
18455 {
18456 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc31) - zc::math::Sin(pos2*PI*2/(dmisc1 == 0 ? 1 : dmisc1))*((int64_t)abs(dmisc31)-abs(dmisc29));
18457 guys.spr(i)->y = -zc::math::Sin(a2+PI/2)*abs(dmisc31) + zc::math::Cos(pos2*PI*2/(dmisc1 == 0 ? 1 : dmisc1))*((int64_t)abs(dmisc31)-abs(dmisc29));
18458 }
18459 else
18460 {
18461 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc29);
18462 guys.spr(i)->y = -zc::math::Sin(a2+PI/2)*abs(dmisc29);
18463 }
18464
18465 temp_x=guys.spr(i)->x;
18466 temp_y=guys.spr(i)->y;
18467 }
18468 else //Oval
18469 {
18470 circle_x = zc::math::Cos(a2+PI/2)*abs(dmisc29);
18471 circle_y = -zc::math::Sin(a2+PI/2)*abs(dmisc29);
18472
18473 if(loopcnt>0)
18474 {
18475 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc29);
18476 guys.spr(i)->y = (-zc::math::Sin(a2+PI/2)-zc::math::Cos(pos2*PI*2/(dmisc1 == 0 ? 1 : dmisc1)))*abs(dmisc31);
18477 }
18478 else
18479 {
18480 guys.spr(i)->x = circle_x;
18481 guys.spr(i)->y = circle_y;
18482 }
18483
18484 temp_x=circle_x;
18485 temp_y=circle_y;
18486 }
18487
18488 double _MSVC2022_tmp1, _MSVC2022_tmp2;
18489 double ddir=atan2_MSVC2022_FIX(double(temp_y),double(temp_x));
18490
18491 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
18492 {
18493 guys.spr(i)->dir=l_down;
18494 }
18495 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
18496 {
18497 guys.spr(i)->dir=left;
18498 }
18499 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
18500 {
18501 guys.spr(i)->dir=l_up;
18502 }
18503 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
18504 {
18505 guys.spr(i)->dir=up;
18506 }
18507 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
18508 {
18509 guys.spr(i)->dir=r_up;
18510 }
18511 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
18512 {
18513 guys.spr(i)->dir=right;
18514 }
18515 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
18516 {
18517 guys.spr(i)->dir=r_down;
18518 }
18519 else
18520 {
18521 guys.spr(i)->dir=down;
18522 }
18523
18524 guys.spr(i)->x += x;
18525 guys.spr(i)->y += y;
18526 }
18527 }
18528
18529 if((wpn>wEnemyWeapons || (wpn >= wScript1 && wpn <= wScript10)) && (dmisc5==1 || dmisc5== 3) && (!dmisc25 || (dmisc25 == 1 && !flycnt && !flycnt2) || (dmisc25 == 2 && (flycnt || flycnt2)) || (dmisc25 == 3 && flycnt2 && !flycnt)))
18530 {
18531 int timeneeded = 48;
18532 int patbreath = (zc_oldrand()%50+50);
18533 if ((patbreath % 4) == 0) ++patbreath;
18534 if (dmisc28 == patratBREATH)
18535 {
18536 timeneeded = 48 + patbreath;
18537 }
18538 if (dmisc28 == patratSTREAM)
18539 {
18540 timeneeded = 48 + 96;
18541 }
18542 if (((((dmisc18 > 0 || ((editorflags & ENEMY_FLAG10) && !flycnt && !flycnt2)) && !(zc_oldrand() % zc_max(dmisc18, 1))) || //New 1/N chance
18543 (dmisc18 == 0 && !(zc_oldrand()&127)) //Old hardcoded firing chance
18544 || (dmisc18 == -1 && loopcnt > 0 && (clk2 == round(halfsize) && (!(editorflags & ENEMY_FLAG3) || !get_bit(quest_rules,qr_NEWENEMYTILES))
18545 || (clk4 == 10 && (editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES)))))
18546 && (clk6 >= 0) //if not in the middle of firing...
18547 && clk6 >= dmisc19) //if over the set cooldown between shots...
18548 && ((!(editorflags & ENEMY_FLAG7) || (loopcnt == 0 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > timeneeded)) || dmisc18 == -1)) //And lastly, if not in danger of starting a loop during the attack.
18549 {
18550 switch(dmisc28)
18551 {
18552 case patratSTREAM:
18553 {
18554 clk7 = 97;
18555 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES)) clk6 = -48;
18556 else clk6 = 0;
18557 break;
18558 }
18559 case patratBREATH:
18560 {
18561 clk7 = patbreath;
18562 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES)) clk6 = -48;
18563 else clk6 = 0;
18564 break;
18565 }
18566 default:
18567 {
18568 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES))
18569 {
18570 clk6 = -48;
18571 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk6) + 16;
18572 }
18573 else
18574 {
18575 clk6 = 0;
18576 if (editorflags & ENEMY_FLAG6) clk4 = 16;
18577 FirePatraWeapon();
18578 }
18579 break;
18580 }
18581 } //ew->setAngle(atan2(double(HeroY()-y),double(HeroX()-x)));
18582 }
18583 if (clk6 < 0)
18584 {
18585 switch(dmisc28)
18586 {
18587 case patratSTREAM:
18588 {
18589 if (clk7 > 0 && (clk7 % 12) == 0) FirePatraWeapon();
18590 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk6) + 16;
18591 break;
18592 }
18593 case patratBREATH:
18594 {
18595 if (clk7 > 0 && (clk7 % 4) == 0) FirePatraWeapon();
18596 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk6) + 16;
18597 break;
18598 }
18599 default:
18600 {
18601 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES) && clk6 == -16)
18602 {
18603 FirePatraWeapon();
18604 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk6) + 16;
18605 }
18606 break;
18607 }
18608 }
18609 }
18610 }
18611
18612 size=.5;
18613 int randattempts = 0;
18614 int randeye = 0;
18615 if (flycnt2 > 0)
18616 {
18617 do
18618 {
18619 randeye = ((flycnt2 > 0) ? (zc_oldrand() % zc_max(1, flycnt2)) : 0);
18620 randeye += (index + flycnt + 1);
18621 ++randattempts;
18622 } while (((esPatra*)guys.spr(randeye))->clk5 < 0 && randattempts < 10);
18623 }
18624 bool dofire = false;
18625 if (dmisc20)
18626 {
18627 if ((dmisc18 > 0 && !(zc_oldrand() % zc_max(dmisc18, 1))) ||
18628 (dmisc18 == 0 && !(zc_oldrand()&127)) ||
18629 (dmisc18 == -1 && (loopcnt > 0 || dmisc20 == 4) && ((clk2 == round(halfsize) && (!(editorflags & ENEMY_FLAG3) || !get_bit(quest_rules,qr_NEWENEMYTILES)) && dmisc20 != 2 && dmisc20 != 4)
18630 || (clk2 == 10 && dmisc20 != 4 && ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES) || dmisc20 == 2))
18631 || ((((((misc%dmisc6) == 0 && (loopcnt == 0 && !dmisc21)) || loopcnt > 1 || loopcnt == -1) && clk2 <= 53 && clk2 >= 51 && (editorflags & ENEMY_FLAG3)) || (!(editorflags & ENEMY_FLAG3) && loopcnt > 0 && clk2 == 1)) && dmisc20 == 4))))
18632 {
18633 if (clk5 >= 0 || !(editorflags & ENEMY_FLAG3) || !get_bit(quest_rules,qr_NEWENEMYTILES))
18634 {
18635 if (clk5 >= dmisc19)
18636 {
18637 if ((!(editorflags & ENEMY_FLAG7) || (loopcnt == 0 &&
18638 (dmisc20 == 2 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > ((int64_t)48 + (int64_t(12)*flycnt2))) ||
18639 (dmisc20 == 4 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > ((int64_t)48 + 96)) ||
18640 (dmisc20 != 2 && dmisc20 != 4 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > 48)))
18641 || dmisc18 == -1)
18642 dofire = true;
18643 }
18644 }
18645 }
18646 }
18647 if(flycnt2)
18648 {
18649 for(int32_t i=index+flycnt+1; i<index+flycnt+flycnt2+1; i++)//inner ring
18650 {
18651 if(!adjusted)
18652 {
18653 ((enemy*)guys.spr(i))->hp=12*game->get_hero_dmgmult();
18654
18655 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18656 {
18657 if (get_bit(quest_rules,qr_PATRAS_USE_HARDCODED_OFFSETS))
18658 {
18659 switch(dmisc5)
18660 {
18661 // Center eye shoots projectiles; make room for its firing tiles
18662 case 1:
18663 case 3:
18664 ((enemy*)guys.spr(i))->o_tile=d->e_tile+120;
18665 break;
18666
18667 // Center eyes does not shoot; use tiles two rows below for inner eyes.
18668 default:
18669 case 2:
18670 ((enemy*)guys.spr(i))->o_tile=d->e_tile+40;
18671 break;
18672 }
18673 }
18674 else ((enemy*)guys.spr(i))->o_tile = d->s_tile;
18675 }
18676 else
18677 {
18678 ((enemy*)guys.spr(i))->o_tile=o_tile+1;
18679 }
18680
18681 ((enemy*)guys.spr(i))->cs=dmisc9;
18682 if (dmisc27) ((enemy*)guys.spr(i))->hp=dmisc27;
18683 }
18684
18685 if(flycnt>0)
18686 {
18687 ((enemy*)guys.spr(i))->superman=true;
18688 }
18689 else
18690 {
18691 ((enemy*)guys.spr(i))->superman=false;
18692 }
18693
18694 if(((enemy*)guys.spr(i))->hp <= 0)
18695 {
18696 for(int32_t j=i; j<index+flycnt+flycnt2; j++)
18697 {
18698 guys.swap(j,j+1);
18699 }
18700
18701 if (--flycnt2 == 0 && dmisc24 != 0) step += zslongToFix(dmisc24*100);
18702 }
18703 else
18704 {
18705 int32_t pos2 = ((enemy*)guys.spr(i))->misc;
18706 double a2 = ((clk2-pos2*basesize/(dmisc2==0 ? 1 : dmisc2))*PI/(halfsize));
18707
18708 if(dmisc4==0)
18709 {
18710 if(loopcnt>0)
18711 {
18712 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc32) - zc::math::Sin(pos2*PI*2/(dmisc2==0?1:dmisc2))*((int64_t)abs(dmisc32)-abs(dmisc30));
18713 guys.spr(i)->y = -zc::math::Sin(a2+PI/2)*abs(dmisc32) + zc::math::Cos(pos2*PI*2/(dmisc2==0?1:dmisc2))*((int64_t)abs(dmisc32)-abs(dmisc30));
18714 }
18715 else
18716 {
18717 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc30);
18718 guys.spr(i)->y = -zc::math::Sin(a2+PI/2)*abs(dmisc30);
18719 }
18720
18721 temp_x=guys.spr(i)->x;
18722 temp_y=guys.spr(i)->y;
18723 }
18724 else
18725 {
18726 circle_x = zc::math::Cos(a2+PI/2)*abs(dmisc30);
18727 circle_y = -zc::math::Sin(a2+PI/2)*abs(dmisc30);
18728
18729 if(loopcnt>0)
18730 {
18731 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc30);
18732 guys.spr(i)->y = (-zc::math::Sin(a2+PI/2)-zc::math::Cos(pos2*PI*2/(dmisc2 == 0 ? 1 : dmisc2)))*abs(dmisc32);
18733 }
18734 else
18735 {
18736 guys.spr(i)->x = circle_x;
18737 guys.spr(i)->y = circle_y;
18738 }
18739
18740 temp_x=circle_x;
18741 temp_y=circle_y;
18742 }
18743
18744 double _MSVC2022_tmp1, _MSVC2022_tmp2;
18745 double ddir=atan2_MSVC2022_FIX(double(temp_y),double(temp_x));
18746
18747 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
18748 {
18749 guys.spr(i)->dir=l_down;
18750 }
18751 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
18752 {
18753 guys.spr(i)->dir=left;
18754 }
18755 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
18756 {
18757 guys.spr(i)->dir=l_up;
18758 }
18759 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
18760 {
18761 guys.spr(i)->dir=up;
18762 }
18763 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
18764 {
18765 guys.spr(i)->dir=r_up;
18766 }
18767 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
18768 {
18769 guys.spr(i)->dir=right;
18770 }
18771 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
18772 {
18773 guys.spr(i)->dir=r_down;
18774 }
18775 else
18776 {
18777 guys.spr(i)->dir=down;
18778 }
18779
18780 guys.spr(i)->x += x;
18781 guys.spr(i)->y = y-guys.spr(i)->y;
18782
18783 if((wpn>wEnemyWeapons || (wpn >= wScript1 && wpn <= wScript10)) && (dmisc5==2 || dmisc5== 3))
18784 {
18785 /*
18786 if(!(zc_oldrand()&127))
18787 {
18788 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID());
18789 sfx(wpnsfx(wpn),pan(int32_t(x)));
18790 }
18791 */
18792 if (((esPatra*)guys.spr(i))->clk5 < 0 && (editorflags & ENEMY_FLAG3))
18793 {
18794 if (((esPatra*)guys.spr(i))->clk4 <= 0 || ((esPatra*)guys.spr(i))->clk5 != -16) ++((esPatra*)guys.spr(i))->clk5;
18795 if (get_bit(quest_rules,qr_PATRAS_USE_HARDCODED_OFFSETS))
18796 {
18797 if (dmisc5 == 3)
18798 {
18799 if (((esPatra*)guys.spr(i))->clk5 >= 0) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+120;
18800 else if (((esPatra*)guys.spr(i))->clk5 >= -16) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+200;
18801 else if (((esPatra*)guys.spr(i))->clk5 >= -48) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+160;
18802 else ((esPatra*)guys.spr(i))->o_tile=d->e_tile+120;
18803 }
18804 else
18805 {
18806 if (((esPatra*)guys.spr(i))->clk5 >= 0) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+40;
18807 else if (((esPatra*)guys.spr(i))->clk5 >= -16) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+120;
18808 else if (((esPatra*)guys.spr(i))->clk5 >= -48) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+80;
18809 else ((esPatra*)guys.spr(i))->o_tile=d->e_tile+40;
18810 }
18811 }
18812 else
18813 {
18814 if (((esPatra*)guys.spr(i))->clk5 >= 0) ((esPatra*)guys.spr(i))->o_tile=d->s_tile;
18815 else if (((esPatra*)guys.spr(i))->clk5 >= -16) ((esPatra*)guys.spr(i))->o_tile=d->s_tile+80;
18816 else if (((esPatra*)guys.spr(i))->clk5 >= -48) ((esPatra*)guys.spr(i))->o_tile=d->s_tile+40;
18817 else ((esPatra*)guys.spr(i))->o_tile=d->s_tile;
18818 }
18819 }
18820 else if ((dmisc19 || ((esPatra*)guys.spr(i))->clk5) && (((esPatra*)guys.spr(i))->clk4 <= 0 || ((esPatra*)guys.spr(i))->clk5 != -16)) ++((esPatra*)guys.spr(i))->clk5;
18821 if (((esPatra*)guys.spr(i))->clk4 > 0) --((esPatra*)guys.spr(i))->clk4;
18822 if (!dmisc25 || (dmisc25 == 1 && !((enemy*)guys.spr(i))->superman) || ((dmisc25 == 2 || dmisc25 == 3) && ((enemy*)guys.spr(i))->superman))
18823 {
18824 switch(dmisc20) //Patra Attack Patterns
18825 {
18826 case 4: //Single one rapidfires
18827 {
18828 if (dofire && i == randeye)
18829 {
18830 ((esPatra*)guys.spr(i))->clk5 = -16;
18831 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES)) ((esPatra*)guys.spr(i))->clk5 = -48;
18832 ((esPatra*)guys.spr(i))->clk4 = 96;
18833 clk5 = -3;
18834 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk5) + 16;
18835 }
18836 if (((esPatra*)guys.spr(i))->clk5 == -16 && (((esPatra*)guys.spr(i))->clk4 % 12) == 0)
18837 {
18838 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18839 sfx(wpnsfx(wpn),pan(int32_t(x)));
18840 }
18841 break;
18842 }
18843 case 3: //Ring
18844 {
18845 if (dofire)
18846 {
18847 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES))
18848 {
18849 ((esPatra*)guys.spr(i))->clk5 = -48;
18850 clk5 = -48;
18851 if (editorflags & ENEMY_FLAG6) clk4 = 64;
18852 }
18853 else
18854 {
18855 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18856 sfx(wpnsfx(wpn),pan(int32_t(x)));
18857 int32_t m=Ewpns.Count()-1;
18858 weapon *ew = (weapon*)(Ewpns.spr(m));
18859
18860 ew->setAngle(atan2(double(HeroY()-y),double(HeroX()-x)));
18861 ((esPatra*)guys.spr(i))->clk5 = 0;
18862 clk5 = 0;
18863 if (editorflags & ENEMY_FLAG6) clk4 = 16;
18864 }
18865 }
18866 if (((esPatra*)guys.spr(i))->clk5 == -16)
18867 {
18868 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18869 sfx(wpnsfx(wpn),pan(int32_t(x)));
18870 int32_t m=Ewpns.Count()-1;
18871 weapon *ew = (weapon*)(Ewpns.spr(m));
18872
18873 ew->setAngle(atan2(double(HeroY()-y),double(HeroX()-x)));
18874 }
18875 break;
18876 }
18877 case 2: //one after another
18878 {
18879 if (dofire)
18880 {
18881 ((esPatra*)guys.spr(i))->clk5 = -48 - (12*(i-(index+flycnt+1)));
18882 clk5 = -48 - (12*flycnt2);
18883 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk5) + 16;
18884 }
18885 if (((esPatra*)guys.spr(i))->clk5 == -16)
18886 {
18887 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18888 sfx(wpnsfx(wpn),pan(int32_t(x)));
18889 }
18890 break;
18891 }
18892 case 1: //random one eye
18893 {
18894 if (dofire && i == randeye)
18895 {
18896 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES))
18897 {
18898 ((esPatra*)guys.spr(i))->clk5 = -48;
18899 clk5 = -48;
18900 if (editorflags & ENEMY_FLAG6) clk4 = 64;
18901 }
18902 else
18903 {
18904 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18905 sfx(wpnsfx(wpn),pan(int32_t(x)));
18906 ((esPatra*)guys.spr(i))->clk5 = 0;
18907 clk5 = 0;
18908 if (editorflags & ENEMY_FLAG6) clk4 = 16;
18909 }
18910 }
18911 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES) && ((esPatra*)guys.spr(i))->clk5 == -16)
18912 {
18913 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18914 sfx(wpnsfx(wpn),pan(int32_t(x)));
18915 }
18916 break;
18917 }
18918 default: //old behavior, all eyes can fire any time
18919 {
18920 if ((((dmisc18 && !(zc_oldrand() % zc_max(dmisc18, 1))) ||
18921 (!dmisc18 && !(zc_oldrand()&127))) && (((esPatra*)guys.spr(i))->clk5 >= 0 || !(editorflags & ENEMY_FLAG3) || !get_bit(quest_rules,qr_NEWENEMYTILES))
18922 && ((esPatra*)guys.spr(i))->clk5 >= dmisc19) && (!(editorflags & ENEMY_FLAG7) || (loopcnt == 0 &&
18923 (dmisc20 != 2 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > 48))))
18924 {
18925 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES))
18926 {
18927 ((esPatra*)guys.spr(i))->clk5 = -48;
18928 if (editorflags & ENEMY_FLAG6) clk4 = 64;
18929 }
18930 else
18931 {
18932 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, fakez);
18933 sfx(wpnsfx(wpn),pan(int32_t(x)));
18934 ((esPatra*)guys.spr(i))->clk5 = 0;
18935 if (editorflags & ENEMY_FLAG6) clk4 = 16;
18936 }
18937 }
18938 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES) && ((esPatra*)guys.spr(i))->clk5 == -16)
18939 {
18940 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, fakez);
18941 sfx(wpnsfx(wpn),pan(int32_t(x)));
18942 }
18943 break;
18944 }
18945 }
18946 }
18947 }
18948
18949 }
18950 }
18951 }
18952
18953 adjusted=true;
18954 return enemy::animate(index);
18955 }
18956
18957 void ePatra::FirePatraWeapon()
18958 { //.707
18959 int32_t xoff = 0;
18960 int32_t yoff = 0;
18961 if ( SIZEflags&guyflagOVERRIDE_HIT_WIDTH )
18962 {
18963 xoff += (hxsz/2)-8;
18964 //Z_scripterrlog("width flag enabled. xoff = %d\n", xoff);
18965 }
18966 if ( SIZEflags&guyflagOVERRIDE_HIT_HEIGHT )
18967 {
18968 yoff += (hysz/2)-8;
18969 //Z_scripterrlog("width flag enabled. yoff = %d\n", yoff);
18970 }
18971 sfx(wpnsfx(wpn),pan(int32_t(x)));
18972 switch (dmisc28)
18973 {
18974 case patrat8SHOT: //Fire Wizzrobe
18975 case patrat4SHOTDIAG:
18976 case patrat4SHOTRAND:
18977 if (dmisc28 != patrat4SHOTRAND || (zc_oldrand()%2)) //if it's the 4 shot rand type, only let it through half the time. Break is within so it doesn't do both, but if it skips this one it'll always do the other one.
18978 {
18979 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,l_up,-1, getUID(),false));
18980 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
18981 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
18982 if (wpn != ewFlame && wpn != ewFlame2) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= .707; //Fire already does this internall for asome bizarre reason.
18983
18984 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,l_down,-1, getUID(),false));
18985 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
18986 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
18987 if (wpn != ewFlame && wpn != ewFlame2) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= .707; //Fire already does this internall for asome bizarre reason.
18988
18989 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,r_up,-1, getUID(),false));
18990 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
18991 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
18992 if (wpn != ewFlame && wpn != ewFlame2) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= .707; //Fire already does this internall for asome bizarre reason.
18993
18994 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,r_down,-1, getUID(),false));
18995 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
18996 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
18997 if (wpn != ewFlame && wpn != ewFlame2) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= .707; //Fire already does this internall for asome bizarre reason.
18998
18999 if (dmisc28 == patrat4SHOTDIAG || dmisc28 == patrat4SHOTRAND) break;
19000 }
19001
19002 [[fallthrough]];
19003 case patrat4SHOTCARD: //Stalfos 3
19004 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,up,-1, getUID(),false));
19005 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19006 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19007 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,down,-1, getUID(),false));
19008 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19009 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19010 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,left,-1, getUID(),false));
19011 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19012 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19013 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,right,-1, getUID(),false));
19014 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19015 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19016 break;
19017
19018 default:
19019 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19020 if (dmisc28 == patratBREATH) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle += (zc_rand(20,-20)/100.0)*PI;
19021 double anglestore = ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle;
19022 if (dmisc28 == patrat1SHOTFAST || dmisc28 == patrat3SHOTFAST || dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19023 if (dmisc28 == patrat3SHOT || dmisc28 == patrat3SHOTFAST || dmisc28 == patrat5SHOT || dmisc28 == patrat5SHOTFAST)
19024 {
19025 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19026 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle = anglestore + (double)0.46364761;
19027 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step += 0.1180;
19028 if (dmisc28 == patrat3SHOTFAST || dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19029 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19030 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle = anglestore - (double)0.46364761;
19031 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step += 0.1180;
19032 if (dmisc28 == patrat3SHOTFAST || dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19033 if (dmisc28 == patrat5SHOT || dmisc28 == patrat5SHOTFAST)
19034 {
19035 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19036 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle = anglestore + (double)0.78539816;
19037 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step += 0.4142;
19038 if (dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19039 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19040 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle = anglestore - (double)0.78539816;
19041 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step += 0.4142;
19042 if (dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19043 }
19044 }
19045 break;
19046
19047 }
19048 sfx(wpnsfx(wpn),pan(int32_t(x)));
19049 //+0.46364761
19050 //11.80
19051 }
19052
19053 void ePatra::draw(BITMAP *dest)
19054 {
19055 tile=o_tile;
19056 update_enemy_frame();
19057 enemy::draw(dest);
19058 }
19059
19060 int32_t ePatra::defend(int32_t wpnId, int32_t *power, int32_t edef)
19061 {
19062 int32_t ret = enemy::defend(wpnId, power, edef);
19063
19064 if(ret < 0 && (flycnt||flycnt2))
19065 return 0;
19066
19067 return ret;
19068 }
19069
19070 int32_t ePatra::defendNew(int32_t wpnId, int32_t *power, int32_t edef, byte unblockable)
19071 {
19072 int32_t ret = enemy::defendNew(wpnId, power, edef, unblockable);
19073
19074 if(ret < 0 && (flycnt||flycnt2))
19075 return 0;
19076
19077 return ret;
19078 }
19079
19080 esPatra::esPatra(zfix X,zfix Y,int32_t Id,int32_t Clk, sprite * prnt) : enemy(X,Y,Id,Clk), parent(prnt)
19081 {
19082 //cs=8;
19083 item_set=0;
19084 misc=clk;
19085 clk4 = 0;
19086 clk5 = 0;
19087 clk = -((misc*21)>>1)-1;
19088 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
19089 hxsz=12;
19090 hysz=12;
19091 hxofs=2;
19092 hyofs=2;
19093 extend = 0;
19094 txsz = 1;
19095 tysz = 1;
19096 /* //These need to be separate enemy editor fields. This enemy class also it's draw altered to correctly support big stuff.
19097 enemy *prntenemy = (enemy *) guys.getByUID(parent->getUID());
19098 int32_t prntSIZEflags = prntenemy->SIZEflags;
19099 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = prntenemy->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
19100 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
19101 // al_trace("Enemy txsz:%i\n", txsz);
19102 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = prntenemy->tysz; if ( tysz > 1 ) extend = 3; }
19103 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = prntenemy->hxsz;
19104 else
19105 hxsz=12;
19106 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = prntenemy->hysz;
19107 else
19108 hysz=12;
19109 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = prntenemy->hzsz;
19110 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = prntenemy->hxofs;
19111 else
19112 hxofs=2;
19113 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = prntenemy->hyofs;
19114 else hyofs=2;
19115 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
19116 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)prntenemy->xofs;
19117 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
19118 {
19119 yofs = (int32_t)prntenemy->yofs; //This seems to be setting to +48 or something with any value set?! -Z
19120 }
19121
19122 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)prntenemy->zofs;
19123 */
19124 mainguy=count_enemy=false;
19125 bgsfx=-1;
19126 //o_tile=0;
19127 flags &= (~guy_neverret);
19128 deadsfx = WAV_EDEAD;
19129 hitsfx = WAV_EHIT;
19130 isCore = false;
19131 }
19132
19133 bool esPatra::animate(int32_t index)
19134 {
19135 if(switch_hooked) return enemy::animate(index);
19136 if(dying)
19137 return Dead(index);
19138
19139 return enemy::animate(index);
19140 }
19141
19142 void esPatra::draw(BITMAP *dest)
19143 {
19144 if(get_bit(quest_rules,qr_NEWENEMYTILES))
19145 {
19146 tile = o_tile+(clk&3);
19147
19148 switch(dir) //directions get screwed up after 8. *shrug*
19149 {
19150 case up: //u
19151 flip=0;
19152 break;
19153
19154 case down: //d
19155 flip=0;
19156 tile+=4;
19157 break;
19158
19159 case left: //l
19160 flip=0;
19161 tile+=8;
19162 break;
19163
19164 case right: //r
19165 flip=0;
19166 tile+=12;
19167 break;
19168
19169 case l_up: //ul
19170 flip=0;
19171 tile+=20;
19172 break;
19173
19174 case r_up: //ur
19175 flip=0;
19176 tile+=24;
19177 break;
19178
19179 case l_down: //dl
19180 flip=0;
19181 tile+=28;
19182 break;
19183
19184 case r_down: //dr
19185 flip=0;
19186 tile+=32;
19187 break;
19188 }
19189 }
19190 else
19191 {
19192 tile = o_tile+((clk&2)>>1);
19193 }
19194
19195 if(clk>=0)
19196 enemy::draw(dest);
19197 }
19198
19199
19200 ePatraBS::ePatraBS(zfix ,zfix ,int32_t Id,int32_t Clk) : enemy((zfix)128,(zfix)48,Id,Clk)
19201 {
19202 adjusted=false;
19203 dir=(zc_oldrand()&7)+8;
19204 step=0.25;
19205 clk4 = 0;
19206 clk5 = 0;
19207 //flycnt=6; flycnt2=0;
19208 flycnt=dmisc1;
19209 flycnt2=0; // PatraBS doesn't have inner rings!
19210 loopcnt=0;
19211
19212 SIZEflags = d->SIZEflags;
19213 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
19214 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
19215 // al_trace("Enemy txsz:%i\n", txsz);
19216 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
19217 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
19218 else hxsz = 32;
19219 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
19220 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
19221 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
19222 else hxofs=-8;
19223 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
19224 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
19225 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
19226 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
19227 {
19228 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
19229 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
19230 }
19231
19232 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
19233
19234 if(dmisc6<int16_t(1))dmisc6=1; // ratio cannot be 0!
19235
19236 //nets+4480;
19237 }
19238
19239 bool ePatraBS::animate(int32_t index)
19240 {
19241 if(switch_hooked) return enemy::animate(index);
19242 if(dying)
19243 return Dead(index);
19244
19245 if(clk==0)
19246 {
19247 removearmos(x,y,ffcactivated);
19248 }
19249
19250 variable_walk_8(rate,homing,hrate,spw_floater);
19251
19252 if(++clk2>90)
19253 {
19254 clk2=0;
19255
19256 if(loopcnt)
19257 --loopcnt;
19258 else
19259 {
19260 if((misc%dmisc6)==0)
19261 loopcnt=dmisc7;
19262 }
19263
19264 ++misc;
19265 }
19266
19267 // double size=1;;
19268 for(int32_t i=index+1; i<index+flycnt+1; i++)
19269 {
19270 if(!adjusted)
19271 {
19272 ((enemy*)guys.spr(i))->hp=dmisc3;
19273
19274 if(get_bit(quest_rules,qr_NEWENEMYTILES))
19275 {
19276 ((enemy*)guys.spr(i))->o_tile=o_tile+dmisc8;
19277 }
19278 else
19279 {
19280 ((enemy*)guys.spr(i))->o_tile=o_tile+1;
19281 }
19282
19283 ((enemy*)guys.spr(i))->cs = dmisc9;
19284 }
19285
19286 if(((enemy*)guys.spr(i))->hp <= 0)
19287 {
19288 for(int32_t j=i; j<index+flycnt+flycnt2; j++)
19289 {
19290 guys.swap(j,j+1);
19291 }
19292
19293 --flycnt;
19294 }
19295 else
19296 {
19297 int32_t pos2 = ((enemy*)guys.spr(i))->misc;
19298 double a2 = ((int64_t)clk2-pos2*90/(dmisc1==0?1:dmisc1))*PI/45;
19299 temp_x = zc::math::Cos(a2+PI/2)*45;
19300 temp_y = -zc::math::Sin(a2+PI/2)*45;
19301
19302 if(loopcnt>0)
19303 {
19304 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*45;
19305 guys.spr(i)->y = (-zc::math::Sin(a2+PI/2)-zc::math::Cos(pos2*PI*2/(dmisc1==0?1:dmisc1)))*22.5;
19306 }
19307 else
19308 {
19309 guys.spr(i)->x = temp_x;
19310 guys.spr(i)->y = temp_y;
19311 }
19312
19313 double _MSVC2022_tmp1, _MSVC2022_tmp2;
19314 double ddir=atan2_MSVC2022_FIX(double(temp_y),double(temp_x));
19315
19316 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
19317 {
19318 guys.spr(i)->dir=l_down;
19319 }
19320 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
19321 {
19322 guys.spr(i)->dir=left;
19323 }
19324 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
19325 {
19326 guys.spr(i)->dir=l_up;
19327 }
19328 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
19329 {
19330 guys.spr(i)->dir=up;
19331 }
19332 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
19333 {
19334 guys.spr(i)->dir=r_up;
19335 }
19336 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
19337 {
19338 guys.spr(i)->dir=right;
19339 }
19340 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
19341 {
19342 guys.spr(i)->dir=r_down;
19343 }
19344 else
19345 {
19346 guys.spr(i)->dir=down;
19347 }
19348
19349 guys.spr(i)->x += x;
19350 guys.spr(i)->y += y;
19351 }
19352 }
19353
19354 adjusted=true;
19355 return enemy::animate(index);
19356 }
19357
19358 void ePatraBS::draw(BITMAP *dest)
19359 {
19360 tile=o_tile;
19361
19362 if(get_bit(quest_rules,qr_NEWENEMYTILES))
19363 {
19364 double _MSVC2022_tmp1, _MSVC2022_tmp2;
19365 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
19366
19367 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
19368 {
19369 lookat=l_down;
19370 }
19371 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
19372 {
19373 lookat=down;
19374 }
19375 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
19376 {
19377 lookat=r_down;
19378 }
19379 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
19380 {
19381 lookat=right;
19382 }
19383 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
19384 {
19385 lookat=r_up;
19386 }
19387 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
19388 {
19389 lookat=up;
19390 }
19391 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
19392 {
19393 lookat=l_up;
19394 }
19395 else
19396 {
19397 lookat=left;
19398 }
19399
19400 switch(lookat) //directions get screwed up after 8. *shrug*
19401 {
19402 case up: //u
19403 flip=0;
19404 break;
19405
19406 case down: //d
19407 flip=0;
19408 tile+=8;
19409 break;
19410
19411 case left: //l
19412 flip=0;
19413 tile+=40;
19414 break;
19415
19416 case right: //r
19417 flip=0;
19418 tile+=48;
19419 break;
19420
19421 case l_up: //ul
19422 flip=0;
19423 tile+=80;
19424 break;
19425
19426 case r_up: //ur
19427 flip=0;
19428 tile+=88;
19429 break;
19430
19431 case l_down: //dl
19432 flip=0;
19433 tile+=120;
19434 break;
19435
19436 case r_down: //dr
19437 flip=0;
19438 tile+=128;
19439 break;
19440 }
19441
19442 tile+=(2*(clk&3));
19443 xofs-=8;
19444 yofs-=8;
19445 drawblock(dest,15);
19446 xofs+=8;
19447 yofs+=8;
19448 }
19449 else
19450 {
19451 flip=(clk&1);
19452 xofs-=8;
19453 yofs-=8;
19454 enemy::draw(dest);
19455 xofs+=16;
19456 enemy::draw(dest);
19457 yofs+=16;
19458 enemy::draw(dest);
19459 xofs-=16;
19460 enemy::draw(dest);
19461 xofs+=8;
19462 yofs-=8;
19463 }
19464 }
19465
19466 int32_t ePatraBS::defend(int32_t wpnId, int32_t *power, int32_t edef)
19467 {
19468 int32_t ret = enemy::defend(wpnId, power, edef);
19469
19470 if(ret < 0 && (flycnt||flycnt2))
19471 return 0;
19472
19473 return ret;
19474 }
19475
19476 int32_t ePatraBS::defendNew(int32_t wpnId, int32_t *power, int32_t edef, byte unblockable)
19477 {
19478 int32_t ret = enemy::defendNew(wpnId, power, edef, unblockable);
19479
19480 if(ret < 0 && (flycnt||flycnt2))
19481 return 0;
19482
19483 return ret;
19484 }
19485
19486 esPatraBS::esPatraBS(zfix X,zfix Y,int32_t Id,int32_t Clk, sprite * prnt) : enemy(X,Y,Id,Clk), parent(prnt)
19487 {
19488 //cs=csBOSS;
19489 item_set=0;
19490 misc=clk;
19491 clk = -((misc*21)>>1)-1;
19492 clk4 = 0;
19493 clk5 = 0;
19494 enemy *prntenemy = (enemy *) guys.getByUID(parent->getUID());
19495 int32_t prntSIZEflags = prntenemy->SIZEflags;
19496 if ( ((prntSIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = prntenemy->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
19497 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
19498 // al_trace("Enemy txsz:%i\n", txsz);
19499 if ( ((prntSIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = prntenemy->tysz; if ( tysz > 1 ) extend = 3; }
19500 if ( ((prntSIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = prntenemy->hxsz;
19501 else hxsz=16;
19502 if ( ((prntSIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = prntenemy->hysz;
19503 else hysz=16;
19504 if ( ((prntSIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = prntenemy->hzsz;
19505 if ( (prntSIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = prntenemy->hxofs;
19506 if ( (prntSIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = prntenemy->hyofs;
19507 else hyofs=2;
19508 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
19509 if ( (prntSIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)prntenemy->xofs;
19510 if ( (prntSIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
19511 {
19512 yofs = (int32_t)prntenemy->yofs;
19513 }
19514 else yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
19515 if ( (prntSIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) prntenemy->zofs = (int32_t)zofs;
19516
19517 bgsfx=-1;
19518 mainguy=count_enemy=false;
19519 deadsfx = WAV_EDEAD;
19520 hitsfx = WAV_EHIT;
19521 flags &= ~guy_neverret;
19522 isCore = false;
19523 }
19524
19525 bool esPatraBS::animate(int32_t index)
19526 {
19527 if(switch_hooked) return enemy::animate(index);
19528 if(dying)
19529 return Dead(index);
19530
19531 return enemy::animate(index);
19532 }
19533
19534 void esPatraBS::draw(BITMAP *dest)
19535 {
19536 tile=o_tile;
19537
19538 if(get_bit(quest_rules,qr_NEWENEMYTILES))
19539 {
19540 switch(dir) //directions get screwed up after 8. *shrug*
19541 {
19542 case up: //u
19543 flip=0;
19544 break;
19545
19546 case down: //d
19547 flip=0;
19548 tile+=4;
19549 break;
19550
19551 case left: //l
19552 flip=0;
19553 tile+=8;
19554 break;
19555
19556 case right: //r
19557 flip=0;
19558 tile+=12;
19559 break;
19560
19561 case l_up: //ul
19562 flip=0;
19563 tile+=20;
19564 break;
19565
19566 case r_up: //ur
19567 flip=0;
19568 tile+=24;
19569 break;
19570
19571 case l_down: //dl
19572 flip=0;
19573 tile+=28;
19574 break;
19575
19576 case r_down: //dr
19577 flip=0;
19578 tile+=32;
19579 break;
19580 }
19581
19582 tile += ((clk&6)>>1);
19583 }
19584 else
19585 {
19586 tile += (clk&4)?1:0;
19587 }
19588
19589 if(clk>=0)
19590 enemy::draw(dest);
19591 }
19592
19593
19594 /**********************************/
19595 /********** Misc Code ***********/
19596 /**********************************/
19597
19598 47 void addEwpn(int32_t x,int32_t y,int32_t z,int32_t id,int32_t type,int32_t power,int32_t dir, int32_t parentid, byte script_generated, int32_t fakez)
19599 {
19600
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
47 if(id>wEnemyWeapons || (id >= wScript1 && id <= wScript10))
19601
4/8
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 47 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 47 times.
✗ Branch 7 not taken.
47 Ewpns.add(new weapon((zfix)x,(zfix)y,(zfix)z,id,type,power,dir, -1, parentid, script_generated));
19602
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 if (fakez > 0) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19603 47 }
19604
19605 175 int32_t hit_enemy(int32_t index, int32_t wpnId,int32_t power,int32_t wpnx,int32_t wpny,int32_t dir, int32_t enemyHitWeapon)
19606 {
19607 // Kludge
19608
4/8
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 175 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 175 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 175 times.
✗ Branch 7 not taken.
175 weapon *w = new weapon((zfix)wpnx,(zfix)wpny,(zfix)0,wpnId,0,power,dir,enemyHitWeapon,-1,false);
19609 175 int32_t ret= ((enemy*)guys.spr(index))->takehit(w);
19610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 175 times.
175 delete w;
19611 175 return ret;
19612 }
19613
19614 20 void enemy_scored(int32_t index)
19615 {
19616 20 ((enemy*)guys.spr(index))->scored=true;
19617 20 }
19618
19619 29 void addguy(int32_t x,int32_t y,int32_t id,int32_t clk,bool mainguy)
19620 {
19621
7/12
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 29 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5 times.
✓ Branch 9 taken 24 times.
✓ Branch 10 taken 29 times.
✗ Branch 11 not taken.
29 guy *g = new guy((zfix)x,(zfix)(y+(isdungeon()?1:0)),id,get_bit(quest_rules,qr_NOGUYPOOF)?0:clk,mainguy);
19622 29 guys.add(g);
19623 29 }
19624
19625 22 void additem(int32_t x,int32_t y,int32_t id,int32_t pickup)
19626 {
19627
5/10
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 22 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 22 times.
✗ Branch 9 not taken.
22 item *i = new item(zfix(x), zfix(y - get_bit(quest_rules, qr_NOITEMOFFSET)), zfix(0), id, pickup, 0);
19628 22 items.add(i);
19629 22 }
19630
19631 void additem(int32_t x,int32_t y,int32_t id,int32_t pickup,int32_t clk)
19632 {
19633 item *i = new item((zfix)x,(zfix)y-(get_bit(quest_rules, qr_NOITEMOFFSET)),(zfix)0,id,pickup,clk);
19634 items.add(i);
19635 }
19636
19637 void adddummyitem(int32_t x,int32_t y,int32_t id,int32_t pickup)
19638 {
19639 item *i = new item((zfix)x,(zfix)y-(get_bit(quest_rules, qr_NOITEMOFFSET)),(zfix)0,id,pickup,0,true);
19640 items.add(i);
19641 }
19642
19643 void kill_em_all()
19644 {
19645 for(int32_t i=0; i<guys.Count(); i++)
19646 {
19647 enemy *e = ((enemy*)guys.spr(i));
19648
19649 if(e->flags&(1<<3) && !(e->family == eeGHINI && e->dmisc1 == 1)) continue;
19650
19651 e->kickbucket();
19652 }
19653 }
19654
19655 bool can_kill_em_all()
19656 {
19657 for(int32_t i=0; i<guys.Count(); i++)
19658 {
19659 enemy *e = ((enemy*)guys.spr(i));
19660
19661 if(e->flags&(1<<3) && !(e->family == eeGHINI && e->dmisc1 == 1)) continue;
19662 if(e->superman) continue;
19663 return true;
19664 }
19665 return false;
19666 }
19667
19668 //This needs a quest rule, or enemy flag, Dying Enemy Doesn't Hurt Hero
19669 // For Hero's hit detection. Don't count them if they are stunned or are guys.
19670 int32_t GuyHit(int32_t tx,int32_t ty,int32_t tz,int32_t txsz,int32_t tysz,int32_t tzsz)
19671 {
19672 for(int32_t i=0; i<guys.Count(); i++)
19673 {
19674 if(guys.spr(i)->hit(tx,ty,tz,txsz,tysz,tzsz))
19675 {
19676 if(((enemy*)guys.spr(i))->stunclk==0 && ((enemy*)guys.spr(i))->frozenclock==0 && (!get_bit(quest_rules, qr_SAFEENEMYFADE) || ((enemy*)guys.spr(i))->fading != fade_flicker)
19677 &&(((enemy*)guys.spr(i))->d->family != eeGUY || ((enemy*)guys.spr(i))->dmisc1))
19678 {
19679 return i;
19680 }
19681 }
19682 }
19683
19684 return -1;
19685 }
19686
19687 64928 int32_t GuyHitFrom(int32_t index,int32_t tx,int32_t ty,int32_t tz,int32_t txsz,int32_t tysz,int32_t tzsz)
19688 {
19689
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 64928 times.
✓ Branch 2 taken 129993 times.
✓ Branch 3 taken 64733 times.
194726 for(int32_t i=zc_max(0, index); i<guys.Count(); i++)
19690 {
19691
2/2
✓ Branch 0 taken 195 times.
✓ Branch 1 taken 129798 times.
129993 if(guys.spr(i)->hit(tx,ty,tz,txsz,tysz,tzsz))
19692 {
19693 195 return i;
19694 }
19695 129798 }
19696
19697 64733 return -1;
19698 64928 }
19699
19700 // For Hero's hit detection. Count them if they are dying.
19701 171 int32_t GuyHit(int32_t index,int32_t tx,int32_t ty,int32_t tz,int32_t txsz,int32_t tysz,int32_t tzsz)
19702 {
19703 171 enemy *e = (enemy*)guys.spr(index);
19704
3/4
✓ Branch 0 taken 171 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 67 times.
✓ Branch 3 taken 104 times.
171 if(!e || e->hp > 0)
19705 67 return -1;
19706
19707 104 bool d = e->dying;
19708 104 int32_t hc = e->hclk;
19709 104 e->dying = false;
19710 104 e->hclk = 0;
19711 104 bool hit = e->hit(tx,ty,tz,txsz,tysz,tzsz);
19712 104 e->dying = d;
19713 104 e->hclk = hc;
19714
19715
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 102 times.
104 return hit ? index : -1;
19716 171 }
19717
19718 68787 bool hasMainGuy()
19719 {
19720
2/2
✓ Branch 0 taken 60534 times.
✓ Branch 1 taken 27633 times.
88167 for(int32_t i=0; i<guys.Count(); i++)
19721 {
19722
2/2
✓ Branch 0 taken 41154 times.
✓ Branch 1 taken 19380 times.
60534 if(((enemy*)guys.spr(i))->mainguy)
19723 {
19724 41154 return true;
19725 }
19726 19380 }
19727
19728 27633 return false;
19729 68787 }
19730
19731 void EatHero(int32_t index)
19732 {
19733 ((eStalfos*)guys.spr(index))->eathero();
19734 }
19735
19736 void GrabHero(int32_t index)
19737 {
19738 ((eWallM*)guys.spr(index))->grabhero();
19739 }
19740
19741 bool CarryHero()
19742 {
19743 for(int32_t i=0; i<guys.Count(); i++)
19744 {
19745 if(((guy*)(guys.spr(i)))->family==eeWALLM)
19746 {
19747 if(((eWallM*)guys.spr(i))->hashero)
19748 {
19749 Hero.x=guys.spr(i)->x;
19750 Hero.y=guys.spr(i)->y;
19751 return ((eWallM*)guys.spr(i))->misc > 0;
19752 }
19753 }
19754
19755 // Like Likes currently can't carry Hero.
19756 /*
19757 if(((guy*)(guys.spr(i)))->family==eeLIKE)
19758 {
19759 if(((eLikeLike*)guys.spr(i))->hashero)
19760 {
19761 Hero.x=guys.spr(i)->x;
19762 Hero.y=guys.spr(i)->y;
19763 return (true);
19764 }
19765 }*/
19766 }
19767
19768 return false;
19769 }
19770
19771 // Move item with guy
19772 void movefairy(zfix &x,zfix &y,int32_t misc)
19773 {
19774 int32_t i = guys.idFirst(eITEMFAIRY+0x1000*misc);
19775
19776 if(i!=-1)
19777 {
19778 x = guys.spr(i)->x;
19779 y = guys.spr(i)->y;
19780 }
19781 }
19782
19783 // Move guy with item (used by FFC scripts and hookshot-dragged fairies)
19784 void movefairy2(zfix x,zfix y,int32_t misc)
19785 {
19786 int32_t i = guys.idFirst(eITEMFAIRY+0x1000*misc);
19787
19788 if(i!=-1)
19789 {
19790 guys.spr(i)->x = x;
19791 guys.spr(i)->y = y;
19792 }
19793 }// Move item with guy
19794
19795 362 void movefairynew(zfix &x,zfix &y, item const &itemfairy)
19796 {
19797 362 enemy *fairy = (enemy *) guys.getByUID(itemfairy.fairyUID);
19798
19799
1/2
✓ Branch 0 taken 362 times.
✗ Branch 1 not taken.
362 if(fairy)
19800 {
19801 362 x = fairy->x;
19802 362 y = fairy->y;
19803 362 }
19804 362 }
19805
19806 // Move guy with item (used by FFC scripts and hookshot-dragged fairies)
19807 void movefairynew2(zfix x,zfix y, item const &itemfairy)
19808 {
19809 enemy *fairy = (enemy *) guys.getByUID(itemfairy.fairyUID);
19810
19811 if(fairy)
19812 {
19813 fairy->x = x;
19814 fairy->y = y;
19815 }
19816 }
19817
19818 void killfairy(int32_t misc)
19819 {
19820 int32_t i = guys.idFirst(eITEMFAIRY+0x1000*misc);
19821 guys.del(i);
19822 }
19823
19824 int32_t getGuyIndex(const int32_t eid)
19825 {
19826 for(word i = 0; i < guys.Count(); i++)
19827 {
19828 if(guys.spr(i)->getUID() == eid)
19829 return i;
19830 }
19831
19832 return -1;
19833 }
19834
19835 void killfairynew(item const &itemfairy)
19836 {
19837 enemy *fairy = (enemy *) guys.getByUID(itemfairy.fairyUID);
19838 if (fairy != NULL) guys.del(getGuyIndex(itemfairy.fairyUID));
19839 }
19840
19841 //Should probably change this to return an 'enemy*', null on failure -Em
19842 54 int32_t addenemy(int32_t x,int32_t y,int32_t id,int32_t clk)
19843 {
19844 54 return addenemy(x,y,0,id,clk);
19845 }
19846
19847 int32_t addchild(int32_t x,int32_t y,int32_t id,int32_t clk, int32_t parent_scriptUID)
19848 {
19849 return addchild(x,y,0,id,clk, parent_scriptUID);
19850 }
19851
19852 int32_t addchild(int32_t x,int32_t y,int32_t z,int32_t id,int32_t clk, int32_t parent_scriptUID)
19853 {
19854 if(id <= 0) return 0;
19855
19856 int32_t ret = 0;
19857 sprite *e=NULL;
19858 al_trace("Adding child\n");
19859
19860 switch(guysbuf[id&0xFFF].family)
19861 {
19862 //Fixme: possible enemy memory leak. (minor)
19863 case eeWALK:
19864 e = new eStalfos((zfix)x,(zfix)y,id,clk);
19865 break;
19866
19867 case eeLEV:
19868 e = new eLeever((zfix)x,(zfix)y,id,clk);
19869 break;
19870
19871 case eeTEK:
19872 e = new eTektite((zfix)x,(zfix)y,id,clk);
19873 break;
19874
19875 case eePEAHAT:
19876 e = new ePeahat((zfix)x,(zfix)y,id,clk);
19877 break;
19878
19879 case eeZORA:
19880 e = new eZora((zfix)x,(zfix)y,id,clk);
19881 break;
19882
19883 case eeGHINI:
19884 e = new eGhini((zfix)x,(zfix)y,id,clk);
19885 break;
19886
19887 case eeKEESE:
19888 e = new eKeese((zfix)x,(zfix)y,id,clk);
19889 break;
19890
19891 case eeWIZZ:
19892 e = new eWizzrobe((zfix)x,(zfix)y,id,clk);
19893 break;
19894
19895 case eePROJECTILE:
19896 e = new eProjectile((zfix)x,(zfix)y,id,clk);
19897 break;
19898
19899 case eeWALLM:
19900 e = new eWallM((zfix)x,(zfix)y,id,clk);
19901 break;
19902
19903 case eeAQUA:
19904 e = new eAquamentus((zfix)x,(zfix)y,id,clk);
19905 break;
19906
19907 case eeMOLD:
19908 e = new eMoldorm((zfix)x,(zfix)y,id,zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)));
19909 break;
19910
19911 case eeMANHAN:
19912 e = new eManhandla((zfix)x,(zfix)y,id,clk);
19913 break;
19914
19915 case eeGLEEOK:
19916 e = new eGleeok((zfix)x,(zfix)y,id,zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)));
19917 break;
19918
19919 case eeGHOMA:
19920 e = new eGohma((zfix)x,(zfix)y,id,clk);
19921 break;
19922
19923 case eeLANM:
19924 e = new eLanmola((zfix)x,(zfix)y,id,zc_max(1,zc_min(253,guysbuf[id&0xFFF].misc1)));
19925 break;
19926
19927 case eeGANON:
19928 e = new eGanon((zfix)x,(zfix)y,id,clk);
19929 break;
19930
19931 case eeFAIRY:
19932 e = new eItemFairy((zfix)x,(zfix)y,id+0x1000*clk,clk);
19933 break;
19934
19935 case eeFIRE:
19936 e = new eFire((zfix)x,(zfix)y,id,clk);
19937 break;
19938
19939 case eeOTHER:
19940 e = new eOther((zfix)x,(zfix)y,id,clk);
19941 break;
19942
19943
19944 case eeSCRIPT01:
19945 case eeSCRIPT02:
19946 case eeSCRIPT03:
19947 case eeSCRIPT04:
19948 case eeSCRIPT05:
19949 case eeSCRIPT06:
19950 case eeSCRIPT07:
19951 case eeSCRIPT08:
19952 case eeSCRIPT09:
19953 case eeSCRIPT10:
19954 case eeSCRIPT11:
19955 case eeSCRIPT12:
19956 case eeSCRIPT13:
19957 case eeSCRIPT14:
19958 case eeSCRIPT15:
19959 case eeSCRIPT16:
19960 case eeSCRIPT17:
19961 case eeSCRIPT18:
19962 case eeSCRIPT19:
19963 case eeSCRIPT20:
19964 {
19965 if ( !get_bit(quest_rules, qr_SCRIPT_FRIENDLY_ENEMY_TYPES) )
19966 {
19967 e = new eScript((zfix)x,(zfix)y,id,clk);
19968 break;
19969 }
19970 else return 0;
19971 }
19972
19973 case eeFFRIENDLY01:
19974 case eeFFRIENDLY02:
19975 case eeFFRIENDLY03:
19976 case eeFFRIENDLY04:
19977 case eeFFRIENDLY05:
19978 case eeFFRIENDLY06:
19979 case eeFFRIENDLY07:
19980 case eeFFRIENDLY08:
19981 case eeFFRIENDLY09:
19982 case eeFFRIENDLY10:
19983 {
19984 if ( !get_bit(quest_rules, qr_SCRIPT_FRIENDLY_ENEMY_TYPES) )
19985 {
19986 e = new eFriendly((zfix)x,(zfix)y,id,clk); break;
19987 }
19988 else return 0;
19989
19990 }
19991
19992 case eeSPINTILE:
19993 e = new eSpinTile((zfix)x,(zfix)y,id,clk);
19994 break;
19995
19996 // and these enemies use the misc10/misc2 value
19997 case eeROCK:
19998 {
19999 switch(guysbuf[id&0xFFF].misc10)
20000 {
20001 case 1:
20002 e = new eBoulder((zfix)x,(zfix)y,id,clk);
20003 break;
20004
20005 case 0:
20006 default:
20007 e = new eRock((zfix)x,(zfix)y,id,clk);
20008 break;
20009 }
20010
20011 break;
20012 }
20013
20014 case eeTRAP:
20015 {
20016 switch(guysbuf[id&0xFFF].misc2)
20017 {
20018 case 1:
20019 e = new eTrap2((zfix)x,(zfix)y,id,clk);
20020 break;
20021
20022 case 0:
20023 default:
20024 e = new eTrap((zfix)x,(zfix)y,id,clk);
20025 break;
20026 }
20027
20028 break;
20029 }
20030
20031 case eeDONGO:
20032 {
20033 switch(guysbuf[id&0xFFF].misc10)
20034 {
20035 case 1:
20036 e = new eDodongo2((zfix)x,(zfix)y,id,clk);
20037 break;
20038
20039 case 0:
20040 default:
20041 e = new eDodongo((zfix)x,(zfix)y,id,clk);
20042 break;
20043 }
20044
20045 break;
20046 }
20047
20048 case eeDIG:
20049 {
20050 switch(guysbuf[id&0xFFF].misc10)
20051 {
20052 case 1:
20053 e = new eLilDig((zfix)x,(zfix)y,id,clk);
20054 break;
20055
20056 case 0:
20057 default:
20058 e = new eBigDig((zfix)x,(zfix)y,id,clk);
20059 break;
20060 }
20061
20062 break;
20063 }
20064
20065 case eePATRA:
20066 {
20067 switch(guysbuf[id&0xFFF].misc10)
20068 {
20069 case 1:
20070 if (get_bit(quest_rules,qr_HARDCODED_BS_PATRA))
20071 {
20072 e = new ePatraBS((zfix)x,(zfix)y,id,clk);
20073 break;
20074 }
20075 [[fallthrough]];
20076 case 0:
20077 default:
20078 e = new ePatra((zfix)x,(zfix)y,id,clk);
20079 break;
20080 }
20081
20082 break;
20083 }
20084
20085 case eeGUY:
20086 {
20087 switch(guysbuf[id&0xFFF].misc10)
20088 {
20089 case 1:
20090 e = new eTrigger((zfix)x,(zfix)y,id,clk);
20091 break;
20092
20093 case 0:
20094 default:
20095 e = new eNPC((zfix)x,(zfix)y,id,clk);
20096 break;
20097 }
20098
20099 break;
20100 }
20101
20102 case eeNONE:
20103 if(guysbuf[id&0xFFF].misc10 ==1)
20104 {
20105 e = new eTrigger((zfix)x,(zfix)y,id,clk);
20106 break;
20107 break;
20108 }
20109 [[fallthrough]];
20110 default:
20111
20112 return 0;
20113 }
20114
20115 ret++; // Made one enemy.
20116
20117 if(z && canfall(id))
20118 {
20119 e->z = (zfix)z;
20120 }
20121
20122 ((enemy*)e)->ceiling = (z && canfall(id));
20123 ((enemy*)e)->parent_script_UID = parent_scriptUID;
20124 //al_trace("Child Script UID: %d\n",((enemy*)e)->script_UID);
20125 //zprint2("Child Script UID: %d\n",((enemy*)e)->script_UID);
20126 //al_trace("Child's Parent UID: %d\n",((enemy*)e)->parent_script_UID);
20127 //zprint2("Child's Parent UID: %d\n",((enemy*)e)->parent_script_UID);
20128
20129
20130 if(!guys.add(e))
20131 {
20132 return 0;
20133 }
20134
20135 // add segments of segmented enemies
20136 int32_t c=0;
20137
20138 switch(guysbuf[id&0xFFF].family)
20139 {
20140 case eeMOLD:
20141 {
20142 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
20143 id &= 0xFFF;
20144
20145 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[id].misc1)); i++)
20146 {
20147 //christ this is messy -DD
20148 int32_t segclk = -i*((int32_t)(8.0/(zslongToFix(guysbuf[id&0xFFF].step*100))));
20149
20150 if(!guys.add(new esMoldorm((zfix)x,(zfix)y,id+0x1000,segclk)))
20151 {
20152 al_trace("Moldorm segment %d could not be created!\n",i+1);
20153
20154 for(int32_t j=0; j<i+1; j++)
20155 guys.del(guys.Count()-1);
20156
20157 return 0;
20158 }
20159
20160 if(i>0)
20161 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
20162
20163 ret++;
20164 }
20165
20166 break;
20167 }
20168
20169 case eeLANM:
20170 {
20171 id &= 0xFFF;
20172 int32_t shft = guysbuf[id].misc2;
20173 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
20174
20175 if(!guys.add(new esLanmola((zfix)x,(zfix)y,id+0x1000,0)))
20176 {
20177 al_trace("Lanmola segment 1 could not be created!\n");
20178 guys.del(guys.Count()-1);
20179 return 0;
20180 }
20181
20182 ret++;
20183
20184 for(int32_t i=1; i<zc_max(1,zc_min(253,guysbuf[id&0xFFF].misc1)); i++)
20185 {
20186 if(!guys.add(new esLanmola((zfix)x,(zfix)y,id+0x2000,-(i<<shft))))
20187 {
20188 al_trace("Lanmola segment %d could not be created!\n",i+1);
20189
20190 for(int32_t j=0; j<i+1; j++)
20191 guys.del(guys.Count()-1);
20192
20193 return 0;
20194 }
20195
20196 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
20197 ret++;
20198 }
20199 }
20200 break;
20201
20202 case eeMANHAN:
20203 id &= 0xFFF;
20204
20205 for(int32_t i=0; i<((!(guysbuf[id].misc2))?4:8); i++)
20206 {
20207 if(!guys.add(new esManhandla((zfix)x,(zfix)y,id+0x1000,i)))
20208 {
20209 al_trace("Manhandla head %d could not be created!\n",i+1);
20210
20211 for(int32_t j=0; j<i+1; j++)
20212 {
20213 guys.del(guys.Count()-1);
20214 }
20215
20216 return 0;
20217 }
20218
20219 ret++;
20220 ((enemy*)guys.spr(guys.Count()-1))->frate=guysbuf[id].misc1;
20221 }
20222
20223 break;
20224
20225 case eeGLEEOK:
20226 {
20227 id &= 0xFFF;
20228
20229 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)); i++)
20230 {
20231 if(!guys.add(new esGleeok((zfix)x,(zfix)y,id+0x1000,c, e)))
20232 {
20233 al_trace("Gleeok head %d could not be created!\n",i+1);
20234
20235 for(int32_t j=0; j<i+1; j++)
20236 {
20237 guys.del(guys.Count()-1);
20238 }
20239
20240 return false;
20241 }
20242
20243 c-=guysbuf[id].misc4;
20244 ret++;
20245 }
20246 }
20247 break;
20248
20249
20250 case eePATRA:
20251 {
20252 id &= 0xFFF;
20253 int32_t outeyes = 0;
20254
20255 for(int32_t i=0; i<zc_min(254,guysbuf[id&0xFFF].misc1); i++)
20256 {
20257 if(!((guysbuf[id].misc10&&get_bit(quest_rules,qr_HARDCODED_BS_PATRA))?guys.add(new esPatraBS((zfix)x,(zfix)y,id+0x1000,i,e)):guys.add(new esPatra((zfix)x,(zfix)y,id+0x1000,i,e))))
20258 {
20259 al_trace("Patra outer eye %d could not be created!\n",i+1);
20260
20261 for(int32_t j=0; j<i+1; j++)
20262 guys.del(guys.Count()-1);
20263
20264 return 0;
20265 }
20266 else
20267 outeyes++;
20268
20269 ret++;
20270 }
20271
20272 for(int32_t i=0; i<zc_min(254,guysbuf[id&0xFFF].misc2); i++)
20273 {
20274 if(!guys.add(new esPatra((zfix)x,(zfix)y,id+0x1000,i,e)))
20275 {
20276 al_trace("Patra inner eye %d could not be created!\n",i+1);
20277
20278 for(int32_t j=0; j<i+1+zc_min(254,outeyes); j++)
20279 guys.del(guys.Count()-1);
20280
20281 return 0;
20282 }
20283
20284 ret++;
20285 }
20286
20287 break;
20288 }
20289 }
20290
20291 return ret;
20292 }
20293
20294 // Returns number of enemies/segments created
20295 369 int32_t addenemy(int32_t x,int32_t y,int32_t z,int32_t id,int32_t clk)
20296 {
20297 //zprint2("addenemy id is: %d\n", (id&0xFFF));
20298 369 int32_t realid = id&0xFFF;
20299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 369 times.
369 if( realid > MAXGUYS )
20300 {
20301 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "addenemy()");
20302 return 0;
20303 }
20304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 369 times.
369 if(id <= 0) return 0;
20305
20306 369 int32_t ret = 0;
20307 369 sprite *e=NULL;
20308
20309
9/31
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 221 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 19 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 88 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
✓ Branch 12 taken 16 times.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 3 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
369 switch(guysbuf[id&0xFFF].family)
20310 {
20311 //Fixme: possible enemy memory leak. (minor)
20312 case eeWALK:
20313
3/6
✓ Branch 0 taken 221 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 221 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 221 times.
✗ Branch 5 not taken.
221 e = new eStalfos((zfix)x,(zfix)y,id,clk);
20314 221 break;
20315
20316 case eeLEV:
20317
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 e = new eLeever((zfix)x,(zfix)y,id,clk);
20318 4 break;
20319
20320 case eeTEK:
20321
3/6
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
19 e = new eTektite((zfix)x,(zfix)y,id,clk);
20322 19 break;
20323
20324 case eePEAHAT:
20325 e = new ePeahat((zfix)x,(zfix)y,id,clk);
20326 break;
20327
20328 case eeZORA:
20329
3/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 e = new eZora((zfix)x,(zfix)y,id,clk);
20330 10 break;
20331
20332 case eeGHINI:
20333 e = new eGhini((zfix)x,(zfix)y,id,clk);
20334 break;
20335
20336 case eeKEESE:
20337
3/6
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
88 e = new eKeese((zfix)x,(zfix)y,id,clk);
20338 88 break;
20339
20340 case eeWIZZ:
20341 e = new eWizzrobe((zfix)x,(zfix)y,id,clk);
20342 break;
20343
20344 case eePROJECTILE:
20345
3/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 e = new eProjectile((zfix)x,(zfix)y,id,clk);
20346 6 break;
20347
20348 case eeWALLM:
20349
3/6
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 e = new eWallM((zfix)x,(zfix)y,id,clk);
20350 16 break;
20351
20352 case eeAQUA:
20353
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 e = new eAquamentus((zfix)x,(zfix)y,id,clk);
20354 2 break;
20355
20356 case eeMOLD:
20357 e = new eMoldorm((zfix)x,(zfix)y,id,zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)));
20358 break;
20359
20360 case eeMANHAN:
20361 e = new eManhandla((zfix)x,(zfix)y,id,clk);
20362 break;
20363
20364 case eeGLEEOK:
20365 e = new eGleeok((zfix)x,(zfix)y,id,zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)));
20366 break;
20367
20368 case eeGHOMA:
20369 e = new eGohma((zfix)x,(zfix)y,id,clk);
20370 break;
20371
20372 case eeLANM:
20373 e = new eLanmola((zfix)x,(zfix)y,id,zc_max(1,zc_min(253,guysbuf[id&0xFFF].misc1)));
20374 break;
20375
20376 case eeGANON:
20377 e = new eGanon((zfix)x,(zfix)y,id,clk);
20378 break;
20379
20380 case eeFAIRY:
20381
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 e = new eItemFairy((zfix)x,(zfix)y,id+0x1000*clk,clk);
20382 3 break;
20383
20384 case eeFIRE:
20385 e = new eFire((zfix)x,(zfix)y,id,clk);
20386 break;
20387
20388 case eeOTHER:
20389 e = new eOther((zfix)x,(zfix)y,id,clk);
20390 break;
20391
20392
20393 case eeSCRIPT01:
20394 case eeSCRIPT02:
20395 case eeSCRIPT03:
20396 case eeSCRIPT04:
20397 case eeSCRIPT05:
20398 case eeSCRIPT06:
20399 case eeSCRIPT07:
20400 case eeSCRIPT08:
20401 case eeSCRIPT09:
20402 case eeSCRIPT10:
20403 case eeSCRIPT11:
20404 case eeSCRIPT12:
20405 case eeSCRIPT13:
20406 case eeSCRIPT14:
20407 case eeSCRIPT15:
20408 case eeSCRIPT16:
20409 case eeSCRIPT17:
20410 case eeSCRIPT18:
20411 case eeSCRIPT19:
20412 case eeSCRIPT20:
20413 {
20414 if ( !get_bit(quest_rules, qr_SCRIPT_FRIENDLY_ENEMY_TYPES) )
20415 {
20416 e = new eScript((zfix)x,(zfix)y,id,clk);
20417 break;
20418 }
20419 else return 0;
20420 }
20421
20422 case eeFFRIENDLY01:
20423 case eeFFRIENDLY02:
20424 case eeFFRIENDLY03:
20425 case eeFFRIENDLY04:
20426 case eeFFRIENDLY05:
20427 case eeFFRIENDLY06:
20428 case eeFFRIENDLY07:
20429 case eeFFRIENDLY08:
20430 case eeFFRIENDLY09:
20431 case eeFFRIENDLY10:
20432 {
20433 if ( !get_bit(quest_rules, qr_SCRIPT_FRIENDLY_ENEMY_TYPES) )
20434 {
20435 e = new eFriendly((zfix)x,(zfix)y,id,clk); break;
20436 }
20437 else return 0;
20438
20439 }
20440
20441 case eeSPINTILE:
20442 e = new eSpinTile((zfix)x,(zfix)y,id,clk);
20443 break;
20444
20445 // and these enemies use the misc10/misc2 value
20446 case eeROCK:
20447 {
20448 switch(guysbuf[id&0xFFF].misc10)
20449 {
20450 case 1:
20451 e = new eBoulder((zfix)x,(zfix)y,id,clk);
20452 break;
20453
20454 case 0:
20455 default:
20456 e = new eRock((zfix)x,(zfix)y,id,clk);
20457 break;
20458 }
20459
20460 break;
20461 }
20462
20463 case eeTRAP:
20464 {
20465 switch(guysbuf[id&0xFFF].misc2)
20466 {
20467 case 1:
20468 e = new eTrap2((zfix)x,(zfix)y,id,clk);
20469 break;
20470
20471 case 0:
20472 default:
20473 e = new eTrap((zfix)x,(zfix)y,id,clk);
20474 break;
20475 }
20476
20477 break;
20478 }
20479
20480 case eeDONGO:
20481 {
20482 switch(guysbuf[id&0xFFF].misc10)
20483 {
20484 case 1:
20485 e = new eDodongo2((zfix)x,(zfix)y,id,clk);
20486 break;
20487
20488 case 0:
20489 default:
20490 e = new eDodongo((zfix)x,(zfix)y,id,clk);
20491 break;
20492 }
20493
20494 break;
20495 }
20496
20497 case eeDIG:
20498 {
20499 switch(guysbuf[id&0xFFF].misc10)
20500 {
20501 case 1:
20502 e = new eLilDig((zfix)x,(zfix)y,id,clk);
20503 break;
20504
20505 case 0:
20506 default:
20507 e = new eBigDig((zfix)x,(zfix)y,id,clk);
20508 break;
20509 }
20510
20511 break;
20512 }
20513
20514 case eePATRA:
20515 {
20516 switch(guysbuf[id&0xFFF].misc10)
20517 {
20518 case 1:
20519 if (get_bit(quest_rules,qr_HARDCODED_BS_PATRA))
20520 {
20521 e = new ePatraBS((zfix)x,(zfix)y,id,clk);
20522 break;
20523 }
20524 [[fallthrough]];
20525 case 0:
20526 default:
20527 e = new ePatra((zfix)x,(zfix)y,id,clk);
20528 break;
20529 }
20530
20531 break;
20532 }
20533
20534 case eeGUY:
20535 {
20536 switch(guysbuf[id&0xFFF].misc10)
20537 {
20538 case 1:
20539 e = new eTrigger((zfix)x,(zfix)y,id,clk);
20540 break;
20541
20542 case 0:
20543 default:
20544 e = new eNPC((zfix)x,(zfix)y,id,clk);
20545 break;
20546 }
20547
20548 break;
20549 }
20550
20551 case eeNONE:
20552 if(guysbuf[id&0xFFF].misc10 ==1)
20553 {
20554 e = new eTrigger((zfix)x,(zfix)y,id,clk);
20555 break;
20556 break;
20557 }
20558 [[fallthrough]];
20559 default:
20560
20561 return 0;
20562 }
20563
20564 369 ret++; // Made one enemy.
20565
20566
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 369 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
369 if(z && canfall(id))
20567 {
20568 e->z = (zfix)z;
20569 }
20570
20571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 369 times.
369 ((enemy*)e)->ceiling = (z && canfall(id));
20572
20573
1/2
✓ Branch 0 taken 369 times.
✗ Branch 1 not taken.
369 if(!guys.add(e))
20574 {
20575 return 0;
20576 }
20577
20578 // add segments of segmented enemies
20579 369 int32_t c=0;
20580
20581
1/6
✓ Branch 0 taken 369 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
369 switch(guysbuf[id&0xFFF].family)
20582 {
20583 case eeMOLD:
20584 {
20585 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
20586 id &= 0xFFF;
20587
20588 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[id].misc1)); i++)
20589 {
20590 //christ this is messy -DD
20591 int32_t segclk = -i*((int32_t)(8.0/(zslongToFix(guysbuf[id&0xFFF].step*100))));
20592
20593 if(!guys.add(new esMoldorm((zfix)x,(zfix)y,id+0x1000,segclk)))
20594 {
20595 al_trace("Moldorm segment %d could not be created!\n",i+1);
20596
20597 for(int32_t j=0; j<i+1; j++)
20598 guys.del(guys.Count()-1);
20599
20600 return 0;
20601 }
20602
20603 if(i>0)
20604 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
20605
20606 ret++;
20607 }
20608
20609 break;
20610 }
20611
20612 case eeLANM:
20613 {
20614 id &= 0xFFF;
20615 int32_t shft = guysbuf[id].misc2;
20616 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
20617
20618 if(!guys.add(new esLanmola((zfix)x,(zfix)y,id+0x1000,0)))
20619 {
20620 al_trace("Lanmola segment 1 could not be created!\n");
20621 guys.del(guys.Count()-1);
20622 return 0;
20623 }
20624
20625 ret++;
20626
20627 for(int32_t i=1; i<zc_max(1,zc_min(253,guysbuf[id&0xFFF].misc1)); i++)
20628 {
20629 if(!guys.add(new esLanmola((zfix)x,(zfix)y,id+0x2000,-(i<<shft))))
20630 {
20631 al_trace("Lanmola segment %d could not be created!\n",i+1);
20632
20633 for(int32_t j=0; j<i+1; j++)
20634 guys.del(guys.Count()-1);
20635
20636 return 0;
20637 }
20638
20639 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
20640 ret++;
20641 }
20642 }
20643 break;
20644
20645 case eeMANHAN:
20646 id &= 0xFFF;
20647
20648 for(int32_t i=0; i<((!(guysbuf[id].misc2))?4:8); i++)
20649 {
20650 if(!guys.add(new esManhandla((zfix)x,(zfix)y,id+0x1000,i)))
20651 {
20652 al_trace("Manhandla head %d could not be created!\n",i+1);
20653
20654 for(int32_t j=0; j<i+1; j++)
20655 {
20656 guys.del(guys.Count()-1);
20657 }
20658
20659 return 0;
20660 }
20661
20662 ret++;
20663 ((enemy*)guys.spr(guys.Count()-1))->frate=guysbuf[id].misc1;
20664 }
20665
20666 break;
20667
20668 case eeGLEEOK:
20669 {
20670 id &= 0xFFF;
20671
20672 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)); i++)
20673 {
20674 if(!guys.add(new esGleeok((zfix)x,(zfix)y,id+0x1000,c, e)))
20675 {
20676 al_trace("Gleeok head %d could not be created!\n",i+1);
20677
20678 for(int32_t j=0; j<i+1; j++)
20679 {
20680 guys.del(guys.Count()-1);
20681 }
20682
20683 return false;
20684 }
20685
20686 c-=guysbuf[id].misc4;
20687 ret++;
20688 }
20689 }
20690 break;
20691
20692
20693 case eePATRA:
20694 {
20695 id &= 0xFFF;
20696 int32_t outeyes = 0;
20697
20698 for(int32_t i=0; i<zc_min(254,guysbuf[id&0xFFF].misc1); i++)
20699 {
20700 if(!((guysbuf[id].misc10&&get_bit(quest_rules,qr_HARDCODED_BS_PATRA))?guys.add(new esPatraBS((zfix)x,(zfix)y,id+0x1000,i,e)):guys.add(new esPatra((zfix)x,(zfix)y,id+0x1000,i,e))))
20701 {
20702 al_trace("Patra outer eye %d could not be created!\n",i+1);
20703
20704 for(int32_t j=0; j<i+1; j++)
20705 guys.del(guys.Count()-1);
20706
20707 return 0;
20708 }
20709 else
20710 outeyes++;
20711
20712 ret++;
20713 }
20714
20715 for(int32_t i=0; i<zc_min(254,guysbuf[id&0xFFF].misc2); i++)
20716 {
20717 if(!guys.add(new esPatra((zfix)x,(zfix)y,id+0x1000,i,e)))
20718 {
20719 al_trace("Patra inner eye %d could not be created!\n",i+1);
20720
20721 for(int32_t j=0; j<i+1+zc_min(254,outeyes); j++)
20722 guys.del(guys.Count()-1);
20723
20724 return 0;
20725 }
20726
20727 ret++;
20728 }
20729
20730 break;
20731 }
20732 }
20733
20734 369 return ret;
20735 369 }
20736
20737 bool isjumper(int32_t id)
20738 {
20739 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20740 {
20741 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "isjumper()");
20742 return false;
20743 }
20744 switch(guysbuf[id&0xFFF].family)
20745 {
20746 case eeROCK:
20747 case eeTEK:
20748 return true;
20749
20750 case eeWALK:
20751 if(guysbuf[id&0xFFF].misc9==e9tVIRE || guysbuf[id&0xFFF].misc9==e9tPOLSVOICE) return true;
20752 }
20753
20754 return false;
20755 }
20756
20757
20758 356 bool isfixedtogrid(int32_t id)
20759 {
20760
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 356 times.
356 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20761 {
20762 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "isfixedtogrid()");
20763 return false;
20764 }
20765
1/2
✓ Branch 0 taken 356 times.
✗ Branch 1 not taken.
356 switch(guysbuf[id&0xFFF].family)
20766 {
20767 case eeWALK:
20768 case eeLEV:
20769 case eeZORA:
20770 case eeDONGO:
20771 case eeGANON:
20772 case eeROCK:
20773 case eeGLEEOK:
20774 case eeAQUA:
20775 case eeLANM:
20776 return true;
20777 }
20778
20779 356 return false;
20780 356 }
20781
20782 // Can't fall, can have Z value.
20783 251382 bool isflier(int32_t id)
20784 {
20785
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 251382 times.
251382 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20786 {
20787 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "isflier()");
20788 return false;
20789 }
20790
2/2
✓ Branch 0 taken 218782 times.
✓ Branch 1 taken 32600 times.
251382 switch(guysbuf[id&0xFFF].family) //id&0x0FFF)
20791 {
20792 case eePEAHAT:
20793 case eeKEESE:
20794 case eePATRA:
20795 case eeFAIRY:
20796 case eeGHINI:
20797
20798 // Could theoretically have their Z set by a script
20799 case eeFIRE:
20800 32600 return true;
20801 break;
20802 }
20803
20804 218782 return false;
20805 251382 }
20806
20807 // Can't have Z position
20808 bool never_in_air(int32_t id)
20809 {
20810 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20811 {
20812 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "never_in_air()");
20813 return false;
20814 }
20815 switch(guysbuf[id&0xFFF].family)
20816 {
20817 case eeMANHAN:
20818 case eeMOLD:
20819 case eeLANM:
20820 case eeGLEEOK:
20821 case eeZORA:
20822 case eeLEV:
20823 case eeAQUA:
20824 case eeROCK:
20825 case eeGANON:
20826 case eeTRAP:
20827 case eePROJECTILE:
20828 case eeSPINTILE:
20829 return true;
20830 }
20831
20832 return false;
20833 }
20834
20835 bool canfall(int32_t id)
20836 {
20837 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20838 {
20839 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "canfall()");
20840 return false;
20841 }
20842 switch(guysbuf[id&0xFFF].family)
20843 {
20844 case eeGUY:
20845 {
20846 if(id < eOCTO1S)
20847 return false;
20848
20849 switch(guysbuf[id&0xFFF].misc10)
20850 {
20851 case 1:
20852 case 2:
20853 return true;
20854
20855 case 0:
20856 case 3:
20857 default:
20858 return false;
20859 }
20860
20861 case eeGHOMA:
20862 case eeDIG:
20863 return false;
20864 }
20865 }
20866
20867
20868 return !never_in_air(id) && !isflier(id) && !isjumper(id);
20869 }
20870
20871 210905 bool enemy::enemycanfall(int32_t id, bool checkgrav)
20872 {
20873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 210905 times.
210905 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20874 {
20875 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "enemycanfall()");
20876 return false;
20877 }
20878 //Z_scripterrlog("canfall family is %d:\n", family);
20879 //Z_scripterrlog("canfall gravity is %s:\n", moveflags & FLAG_OBEYS_GRAV ? "true" : "false");
20880 //if ( family == eeFIRE && id >= eSTART )
20881 //{
20882 // Z_scripterrlog("eeFire\n");
20883 // return moveflags & FLAG_OBEYS_GRAV; //'Other' enemy class, used by scripts. -Z
20884 //}
20885
20886 //In ZQ, eeFIRE is Other(floating) and eeOTHER is 'other'.
20887
20888
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 196693 times.
✓ Branch 2 taken 14212 times.
210905 switch(guysbuf[id&0xFFF].family)
20889 {
20890 case eeGUY:
20891 {
20892
1/2
✓ Branch 0 taken 14212 times.
✗ Branch 1 not taken.
14212 if(id < eOCTO1S) //screen guys and fires that aren't real enemies, and never fall
20893 14212 return false;
20894
20895 switch(guysbuf[id&0xFFF].misc10) //I'm unsure what these specify off-hand. Needs better comments. -Z
20896 {
20897 case 1:
20898 case 2:
20899 return true;
20900
20901 case 0:
20902 case 3:
20903 default:
20904 return false;
20905 }
20906
20907 case eeGHOMA:
20908 case eeDIG:
20909 return false;
20910 }
20911 }
20912
20913
2/2
✓ Branch 0 taken 136668 times.
✓ Branch 1 taken 60025 times.
196693 if(!checkgrav) return true;
20914 136668 return (moveflags & FLAG_OBEYS_GRAV);
20915
20916 // if ( isflier(id) || isjumper(id) || never_in_air(id) )
20917 // {
20918 // if ( moveflags & FLAG_OBEYS_GRAV ) return true;
20919 // else return false;
20920 // }
20921 // else
20922 // {
20923 // return (moveflags & FLAG_OBEYS_GRAV);
20924 // }
20925 //return !never_in_air(id) && !isflier(id) && !isjumper(id);
20926 210905 }
20927
20928 13 void addfires()
20929 {
20930
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 if(!get_bit(quest_rules,qr_NOGUYFIRES))
20931 {
20932 8 int32_t bs = get_bit(quest_rules,qr_BSZELDA);
20933 8 addguy(bs? 64: 72,64,gFIRE,-17,false);
20934 8 addguy(bs?176:168,64,gFIRE,-18,false);
20935 8 }
20936 13 }
20937
20938 155 void loadguys()
20939 {
20940
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 155 times.
155 if(loaded_guys)
20941 return;
20942
20943 155 loaded_guys=true;
20944
20945 155 byte Guy=0;
20946 // When in caves/item rooms, use mSPECIALITEM and ipONETIME2
20947 // Else use mITEM and ipONETIME
20948 155 int32_t mf = (currscr>=128) ? mSPECIALITEM : mITEM;
20949 155 int32_t onetime = (currscr>=128) ? ipONETIME2 : ipONETIME;
20950
20951 155 repaircharge=0;
20952 155 adjustmagic=false;
20953 155 learnslash=false;
20954
20955
2/2
✓ Branch 0 taken 465 times.
✓ Branch 1 taken 155 times.
620 for(int32_t i=0; i<3; i++)
20956 {
20957 465 prices[i]=0;
20958 465 }
20959
20960 155 hasitem=0;
20961
20962
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 143 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 10 times.
155 if(currscr>=128 && DMaps[currdmap].flags&dmfGUYCAVES)
20963 {
20964
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(DMaps[currdmap].flags&dmfCAVES)
20965 {
20966 10 Guy=tmpscr[1].guy;
20967 10 }
20968 10 }
20969 else
20970 {
20971 145 Guy=tmpscr->guy;
20972
20973
4/4
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 109 times.
✓ Branch 3 taken 34 times.
145 if(currscr < 0x80 && (DMaps[currdmap].flags&dmfVIEWMAP))
20974 34 game->maps[(currmap*MAPSCRSNORMAL)+currscr] |= mVISITED; // mark as visited
20975 }
20976
20977 // The Guy appears if 'Hero is in cave' equals 'Guy is in cave'.
20978
4/4
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 91 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 13 times.
155 if(Guy && ((currscr>=128) == !!(DMaps[currdmap].flags&dmfGUYCAVES)))
20979 {
20980
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if(tmpscr->room==rZELDA)
20981 {
20982 addguy(120,72,Guy,-15,true);
20983 guys.spr(0)->hxofs=1000;
20984 addenemy(128,96,eFIRE,-15);
20985 addenemy(112,96,eFIRE,-15);
20986 addenemy(96,120,eFIRE,-15);
20987 addenemy(144,120,eFIRE,-15);
20988 return;
20989 }
20990
20991
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13 if(Guy!=gFAIRY || !get_bit(quest_rules,qr_NOFAIRYGUYFIRES))
20992 13 addfires();
20993
20994
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 10 times.
13 if(currscr>=128)
20995
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if(getmapflag() && !(tmpscr->flags9&fBELOWRETURN))
20996 Guy=0;
20997
20998
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
13 switch(tmpscr->room)
20999 {
21000 case rSP_ITEM:
21001 case rGRUMBLE:
21002 case rBOMBS:
21003 case rARROWS:
21004 case rSWINDLE:
21005 case rMUPGRADE:
21006 case rLEARNSLASH:
21007 case rTAKEONE:
21008 if((get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag((currscr < 128) ? mITEM : mSPECIALITEM)) || (!get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag() && !(tmpscr->flags9&fBELOWRETURN))) //get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)
21009 Guy=0;
21010
21011 break;
21012
21013 case rREPAIR:
21014 if (get_bit(quest_rules, qr_OLD_DOORREPAIR)) break;
21015 if((get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag((currscr < 128) ? mITEM : mSPECIALITEM)) || (!get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag() && !(tmpscr->flags9&fBELOWRETURN))) //get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)
21016 Guy=0;
21017
21018 break;
21019 case rRP_HC:
21020 if (get_bit(quest_rules, qr_OLD_POTION_OR_HC)) break;
21021 if((get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag((currscr < 128) ? mITEM : mSPECIALITEM)) || (!get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag() && !(tmpscr->flags9&fBELOWRETURN))) //get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)
21022 Guy=0;
21023
21024 break;
21025 case rMONEY:
21026 if (get_bit(quest_rules, qr_OLD_SECRETMONEY)) break;
21027 if((get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag((currscr < 128) ? mITEM : mSPECIALITEM)) || (!get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag() && !(tmpscr->flags9&fBELOWRETURN))) //get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)
21028 Guy=0;
21029
21030 break;
21031
21032 case rTRIFORCE:
21033 {
21034 int32_t tc = TriforceCount();
21035
21036 if(get_bit(quest_rules,qr_4TRI))
21037 {
21038 if((get_bit(quest_rules,qr_3TRI) && tc>=3) || tc>=4)
21039 Guy=0;
21040 }
21041 else
21042 {
21043 if((get_bit(quest_rules,qr_3TRI) && tc>=6) || tc>=8)
21044 Guy=0;
21045 }
21046 }
21047 break;
21048 }
21049
21050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if(Guy)
21051 {
21052
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13 if(Guy!=gFAIRY || !get_bit(quest_rules,qr_NOFAIRYGUYFIRES))
21053 13 blockpath=true;
21054
21055
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 3 times.
13 if(currscr<128)
21056 3 sfx(WAV_SCALE);
21057
21058
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
13 addguy(120,64,Guy, (dlevel||BSZ)?-15:startguy[zc_oldrand()&7], true);
21059 13 Hero.Freeze();
21060 13 }
21061 13 }
21062
1/2
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
142 else if(Guy==gFAIRY) // The only Guy that somewhat ignores the "Guys In Caves Only" DMap flag
21063 {
21064 sfx(WAV_SCALE);
21065 addguy(120,62,gFAIRY,-14,false);
21066 }
21067
21068 155 loaditem();
21069
21070 // Collecting a rupee in a '10 Rupees' screen sets the mITEM screen state if
21071 // it doesn't appear in a Cave/Item Cellar, and the mSPECIALITEM screen state if it does.
21072
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
155 if(tmpscr->room==r10RUPIES && !getmapflag(mf))
21073 {
21074 //setmapflag();
21075 for(int32_t i=0; i<10; i++)
21076 additem(ten_rupies_x[i],ten_rupies_y[i],0,ipBIGRANGE+onetime,-14);
21077 }
21078 155 }
21079
21080 155 void loaditem()
21081 {
21082 155 byte Item = 0;
21083
21084
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 12 times.
155 if(currscr<128)
21085 {
21086 143 Item=tmpscr->item;
21087
21088
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 135 times.
✓ Branch 2 taken 113 times.
✓ Branch 3 taken 30 times.
143 if((!getmapflag(mITEM) || (tmpscr->flags9&fITEMRETURN)) && (tmpscr->hasitem != 0))
21089 {
21090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if(tmpscr->flags8&fSECRETITEM)
21091 hasitem=8;
21092
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 else if(tmpscr->flags&fITEM)
21093 20 hasitem=1;
21094
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
10 else if(tmpscr->enemyflags&efCARRYITEM)
21095 3 hasitem=4; // Will be set to 2 by roaming_item
21096 else
21097
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
14 items.add(new item((zfix)tmpscr->itemx,
21098
4/14
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 7 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 7 times.
✗ Branch 13 not taken.
7 (tmpscr->flags7&fITEMFALLS && isSideViewGravity()) ? (zfix)-170 : (zfix)tmpscr->itemy+(get_bit(quest_rules, qr_NOITEMOFFSET)?0:1),
21099
2/10
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 7 times.
✗ Branch 9 not taken.
7 (tmpscr->flags7&fITEMFALLS && !(isSideViewGravity())) ? (zfix)170 : (zfix)0,
21100
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
7 Item,ipONETIME|ipBIGRANGE|((itemsbuf[Item].family==itype_triforcepiece ||
21101 7 (tmpscr->flags3&fHOLDITEM)) ? ipHOLDUP : 0) | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0),0));
21102 30 }
21103 143 }
21104
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2 times.
12 else if(!(DMaps[currdmap].flags&dmfCAVES))
21105 {
21106
2/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 if((!getmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM) || (tmpscr[1].flags9&fBELOWRETURN)) && tmpscr[1].room==rSP_ITEM
21107
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
2 && (currscr==128 || !get_bit(quest_rules,qr_ITEMSINPASSAGEWAYS)))
21108 {
21109 1 Item=tmpscr[1].catchall;
21110
21111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(Item)
21112
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 items.add(new item((zfix)tmpscr->itemx,
21113
4/14
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
1 (tmpscr->flags7&fITEMFALLS && isSideViewGravity()) ? (zfix)-170 : (zfix)tmpscr->itemy+(get_bit(quest_rules, qr_NOITEMOFFSET)?0:1),
21114
2/10
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
1 (tmpscr->flags7&fITEMFALLS && !(isSideViewGravity())) ? (zfix)170 : (zfix)0,
21115 1 Item,ipONETIME2|ipBIGRANGE|ipHOLDUP | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0),0));
21116 1 }
21117 2 }
21118 155 }
21119
21120 2 void never_return(int32_t index)
21121 {
21122
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!get_bit(quest_rules,qr_KILLALL))
21123 1 goto doit;
21124
21125
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for(int32_t i=0; i<guys.Count(); i++)
21126
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if(((((enemy*)guys.spr(i))->d->flags)&guy_neverret) && i!=index)
21127 {
21128 goto dontdoit;
21129 1 }
21130
21131 doit:
21132 2 setmapflag(mNEVERRET);
21133 dontdoit:
21134 2 return;
21135 }
21136
21137 315 bool slowguy(int32_t id)
21138 {
21139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 315 times.
315 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
21140 {
21141 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "slowguy()");
21142 return false;
21143 }
21144 //return (guysbuf[id].step<100);
21145
2/2
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 83 times.
315 switch(id)
21146 {
21147 case eOCTO1S:
21148 case eOCTO2S:
21149 case eOCTO1F:
21150 case eOCTO2F:
21151 case eLEV1:
21152 case eLEV2:
21153 case eROCK:
21154 case eBOULDER:
21155 83 return true;
21156 }
21157
21158 232 return false;
21159 315 }
21160
21161 342 bool ok2add(int32_t id)
21162 {
21163
2/4
✓ Branch 0 taken 342 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 342 times.
342 if( ((unsigned)(id&0xFFF)) > MAXGUYS || id <= 0)
21164 {
21165 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "oktoadd()");
21166 return false;
21167 }
21168
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 342 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
342 if(getmapflag(mNEVERRET) && (guysbuf[id].flags & guy_neverret))
21169 return false;
21170
21171
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 342 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
342 switch(guysbuf[id].family)
21172 {
21173 // I added a special case for shooters because having traps on the same screen
21174 // was preventing them from spawning due to TMPNORET. This means they will
21175 // never stay dead, though, so it may not be the best solution. - Saf
21176 case eePROJECTILE:
21177 return true;
21178
21179
21180 case eeDIG:
21181 {
21182 switch(guysbuf[id].misc10)
21183 {
21184 case 1:
21185 if(!get_bit(quest_rules,qr_NOTMPNORET))
21186 return !getmapflag(mTMPNORET);
21187
21188 return true;
21189
21190 case 0:
21191 default:
21192 return true;
21193 }
21194 }
21195 case eeGANON:
21196 case eeTRAP:
21197 if ((guysbuf[id].family == eeGANON && !get_bit(quest_rules, qr_CAN_PLACE_GANON))
21198 || (guysbuf[id].family == eeTRAP && !get_bit(quest_rules, qr_CAN_PLACE_TRAPS))) return false;
21199 [[fallthrough]];
21200 default:
21201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 342 times.
342 if (guysbuf[id].flags2&guy_ignoretmpnr) return true;
21202 342 break;
21203 }
21204
21205
2/2
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 168 times.
342 if(!get_bit(quest_rules,qr_NOTMPNORET))
21206 168 return !getmapflag(mTMPNORET);
21207
21208 174 return true;
21209 342 }
21210
21211 1854 void activate_fireball_statue(int32_t pos)
21212 {
21213
3/4
✓ Branch 0 taken 352 times.
✓ Branch 1 taken 1502 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 352 times.
1854 if(!(tmpscr->enemyflags&efFIREBALLS) || statueID<0)
21214 {
21215 1502 return;
21216 }
21217
21218 352 int32_t cx=-1000, cy=-1000;
21219 352 int32_t x = (pos&15)<<4;
21220 352 int32_t y = pos&0xF0;
21221
21222 352 int32_t ctype = combobuf[MAPCOMBO(x,y)].type;
21223
21224
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 352 times.
352 if(!isfixedtogrid(statueID))
21225 {
21226
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 352 times.
352 if(ctype==cL_STATUE)
21227 {
21228 cx=x+4;
21229 cy=y+7;
21230 }
21231
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 348 times.
352 else if(ctype==cR_STATUE)
21232 {
21233 4 cx=x-8;
21234 4 cy=y-1;
21235 4 }
21236
1/2
✓ Branch 0 taken 348 times.
✗ Branch 1 not taken.
348 else if(ctype==cC_STATUE)
21237 {
21238 cx=x;
21239 cy=y;
21240 }
21241 352 }
21242 else if(ctype==cL_STATUE || ctype==cR_STATUE || ctype==cC_STATUE)
21243 {
21244 cx=x;
21245 cy=y;
21246 }
21247
21248
2/2
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 4 times.
352 if(cx!=-1000) // No point creating it if this is false
21249 {
21250
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 for(int32_t j=0; j<guys.Count(); j++)
21251 {
21252
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy))
21253 {
21254 if((guys.spr(j)->id&0xFFF) == statueID) // There's already a matching enemy here!
21255 return; // No point deleting it. A script might be toying with it in some way.
21256 else
21257 guys.del(j);
21258 }
21259 2 }
21260
21261 4 addenemy(cx, cy, statueID, !isfixedtogrid(statueID) ? 24 : 0);
21262 4 }
21263 1854 }
21264
21265 155 void activate_fireball_statues()
21266 {
21267
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 153 times.
155 if(!(tmpscr->enemyflags&efFIREBALLS))
21268 {
21269 153 return;
21270 }
21271
21272
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 352 times.
354 for(int32_t i=0; i<176; i++)
21273 {
21274 352 activate_fireball_statue(i);
21275 352 }
21276 155 }
21277
21278 155 void load_default_enemies()
21279 {
21280 155 wallm_load_clk=frame-80;
21281 155 int32_t Id=0;
21282
21283
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 10 times.
155 if(tmpscr->enemyflags&efZORA)
21284 {
21285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(zoraID>=0)
21286 10 addenemy(-16, -16, zoraID, 0);
21287 10 }
21288
21289
1/2
✓ Branch 0 taken 155 times.
✗ Branch 1 not taken.
155 if(tmpscr->enemyflags&efTRAP4)
21290 {
21291 if(cornerTrapID>=0)
21292 {
21293 addenemy(32, 32, cornerTrapID, -14);
21294 addenemy(208, 32, cornerTrapID, -14);
21295 addenemy(32, 128, cornerTrapID, -14);
21296 addenemy(208, 128, cornerTrapID, -14);
21297 }
21298 }
21299
21300
2/2
✓ Branch 0 taken 1705 times.
✓ Branch 1 taken 155 times.
1860 for(int32_t y=0; y<176; y+=16)
21301 {
21302
2/2
✓ Branch 0 taken 27280 times.
✓ Branch 1 taken 1705 times.
28985 for(int32_t x=0; x<256; x+=16)
21303 {
21304 27280 int32_t ctype = combobuf[MAPCOMBO(x,y)].type;
21305 27280 int32_t cflag = MAPFLAG(x, y);
21306 27280 int32_t cflag_i = MAPCOMBOFLAG(x, y);
21307
21308
3/6
✓ Branch 0 taken 27280 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27280 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 27280 times.
27280 if(ctype==cTRAP_H || cflag==mfTRAP_H || cflag_i==mfTRAP_H)
21309 {
21310 if(trapLOSHorizontalID>=0)
21311 addenemy(x, y, trapLOSHorizontalID, -14);
21312 }
21313
3/6
✓ Branch 0 taken 27280 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27280 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 27280 times.
27280 else if(ctype==cTRAP_V || cflag==mfTRAP_V || cflag_i==mfTRAP_V)
21314 {
21315 if(trapLOSVerticalID>=0)
21316 addenemy(x, y, trapLOSVerticalID, -14);
21317 }
21318
3/6
✓ Branch 0 taken 27280 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27280 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 27280 times.
27280 else if(ctype==cTRAP_4 || cflag==mfTRAP_4 || cflag_i==mfTRAP_4)
21319 {
21320 if(trapLOS4WayID>=0)
21321 {
21322 if(addenemy(x, y, trapLOS4WayID, -14))
21323 guys.spr(guys.Count()-1)->dummy_int[1]=2;
21324 }
21325 }
21326
21327
3/6
✓ Branch 0 taken 27280 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27280 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 27280 times.
27280 else if(ctype==cTRAP_LR || cflag==mfTRAP_LR || cflag_i==mfTRAP_LR)
21328 {
21329 if(trapConstantHorizontalID>=0)
21330 addenemy(x, y, trapConstantHorizontalID, -14);
21331 }
21332
3/6
✓ Branch 0 taken 27280 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27280 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 27280 times.
27280 else if(ctype==cTRAP_UD || cflag==mfTRAP_UD || cflag_i==mfTRAP_UD)
21333 {
21334 if(trapConstantVerticalID>=0)
21335 addenemy(x, y, trapConstantVerticalID, -14);
21336 }
21337
21338
1/2
✓ Branch 0 taken 27280 times.
✗ Branch 1 not taken.
27280 if(ctype==cSPINTILE1)
21339 {
21340 // Awaken spinning tile
21341 awaken_spinning_tile(tmpscr,COMBOPOS(x,y));
21342 }
21343 27280 }
21344 1705 }
21345
21346
1/2
✓ Branch 0 taken 155 times.
✗ Branch 1 not taken.
155 if(tmpscr->enemyflags&efTRAP2)
21347 {
21348 if(centerTrapID>=-1)
21349 {
21350 if(addenemy(64, 80, centerTrapID, -14))
21351 guys.spr(guys.Count()-1)->dummy_int[1]=1;
21352
21353 if(addenemy(176, 80, centerTrapID, -14))
21354 guys.spr(guys.Count()-1)->dummy_int[1]=1;
21355 }
21356 }
21357
21358
1/2
✓ Branch 0 taken 155 times.
✗ Branch 1 not taken.
155 if(tmpscr->enemyflags&efROCKS)
21359 {
21360 if(rockID>=0)
21361 {
21362 addenemy(zc_oldrand()&0xF0, 0, rockID, 0);
21363 addenemy(zc_oldrand()&0xF0, 0, rockID, 0);
21364 addenemy(zc_oldrand()&0xF0, 0, rockID, 0);
21365 }
21366 }
21367
21368 155 activate_fireball_statues();
21369 155 }
21370
21371 191230 void update_slope_combopos(int32_t lyr, int32_t pos)
21372 {
21373
2/4
✓ Branch 0 taken 191230 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 191230 times.
191230 if(unsigned(lyr) > 6 || unsigned(pos) > 175) return;
21374 191230 mapscr* s = FFCore.tempScreens[lyr];
21375 191230 newcombo const& cmb = combobuf[s->data[pos]];
21376
21377 191230 auto id = (176*lyr)+pos;
21378 191230 auto it = slopes.find(id);
21379
21380 191230 bool wasSlope = it!=slopes.end();
21381 191230 bool isSlope = cmb.type == cSLOPE;
21382
21383
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 191230 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
191230 if(isSlope && !wasSlope)
21384 {
21385 slopes.try_emplace(id, &(s->data[pos]), nullptr, id, pos);
21386 }
21387
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 191230 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
191230 else if(wasSlope && !isSlope)
21388 {
21389 slopes.erase(it);
21390 }
21391 191230 }
21392 155 void update_slope_comboposes()
21393 {
21394
2/2
✓ Branch 0 taken 1085 times.
✓ Branch 1 taken 155 times.
1240 for(auto lyr = 0; lyr < 7; ++lyr)
21395 {
21396
2/2
✓ Branch 0 taken 190960 times.
✓ Branch 1 taken 1085 times.
192045 for(auto pos = 0; pos < 176; ++pos)
21397 190960 update_slope_combopos(lyr,pos);
21398 1085 }
21399 155 }
21400
21401 // Everything that must be done before we change a screen's combo to another combo, or a combo's type to another type.
21402 // There's 2 routines because it's unclear if combobuf or tmpscr->data gets modified. -L
21403 1502 void screen_combo_modify_preroutine(mapscr *s, int32_t pos)
21404 {
21405 1502 delete_fireball_shooter(s, pos);
21406 1502 }
21407
21408 //Placeholder in case we need it.
21409 void screen_ffc_modify_preroutine(word index)
21410 {
21411 return;
21412 }
21413
21414 // Everything that must be done after we change a screen's combo to another combo. -L
21415 1502 void screen_combo_modify_postroutine(mapscr *s, int32_t pos)
21416 {
21417 1502 s->valid |= mVALID;
21418 1502 activate_fireball_statue(pos);
21419
21420
1/2
✓ Branch 0 taken 1502 times.
✗ Branch 1 not taken.
1502 if(combobuf[s->data[pos]].type==cSPINTILE1)
21421 {
21422 // Awaken spinning tile
21423 awaken_spinning_tile(s,pos);
21424 }
21425 1502 int32_t lyr = -1;
21426
2/2
✓ Branch 0 taken 1232 times.
✓ Branch 1 taken 270 times.
1502 if(s == tmpscr) lyr = 0;
21427
2/2
✓ Branch 0 taken 1232 times.
✓ Branch 1 taken 7392 times.
8624 else for(size_t q = 0; q < 6; ++q)
21428 {
21429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7392 times.
7392 if(s == tmpscr2+q)
21430 {
21431 lyr = q+1;
21432 break;
21433 }
21434 7392 }
21435
2/2
✓ Branch 0 taken 1232 times.
✓ Branch 1 taken 270 times.
1502 if(lyr > -1)
21436 270 update_slope_combopos(lyr,pos);
21437 1502 }
21438
21439 22791 void screen_ffc_modify_postroutine(word index)
21440 {
21441 22791 ffcdata& ff = tmpscr->ffcs[index];
21442 22791 newcombo const& cmb = combobuf[ff.getData()];
21443
21444 22791 auto id = (176*7)+int32_t(index);
21445 22791 auto it = slopes.find(id);
21446
21447 22791 bool wasSlope = it!=slopes.end();
21448
2/2
✓ Branch 0 taken 22786 times.
✓ Branch 1 taken 5 times.
22791 bool isSlope = cmb.type == cSLOPE && !(ff.flags&ffCHANGER);
21449
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 22786 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
22791 if(isSlope && !wasSlope)
21450 {
21451 5 slopes.try_emplace(id, nullptr, &ff, id);
21452 5 }
21453
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 22786 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
22786 else if(wasSlope && !isSlope)
21454 {
21455 slopes.erase(it);
21456 }
21457 22791 }
21458
21459 void screen_combo_modify_pre(int32_t cid)
21460 {
21461 for(auto lyr = 0; lyr < 7; ++lyr)
21462 {
21463 mapscr* t = FFCore.tempScreens[lyr];
21464 for(int32_t i = 0; i < 176; i++)
21465 {
21466 if(t->data[i] == cid)
21467 {
21468 screen_combo_modify_preroutine(t,i);
21469 }
21470 }
21471 }
21472 }
21473 void screen_combo_modify_post(int32_t cid)
21474 {
21475 for(auto lyr = 0; lyr < 7; ++lyr)
21476 {
21477 mapscr* t = FFCore.tempScreens[lyr];
21478 for(int32_t i = 0; i < 176; i++)
21479 {
21480 if(t->data[i] == cid)
21481 {
21482 screen_combo_modify_postroutine(t,i);
21483 }
21484 }
21485 }
21486 for(word ind = 0; ind < MAXFFCS; ++ind)
21487 {
21488 if(tmpscr->ffcs[ind].getData() == cid)
21489 screen_ffc_modify_postroutine(ind);
21490 }
21491 }
21492
21493 void awaken_spinning_tile(mapscr *s, int32_t pos)
21494 {
21495 addenemy((pos&15)<<4,pos&0xF0,(s->cset[pos]<<12)+eSPINTILE1,combobuf[s->data[pos]].o_tile+zc_max(1,combobuf[s->data[pos]].frames));
21496 }
21497
21498
21499 // It stands for next_side_pos
21500 128 void nsp(bool random)
21501 // moves sle_x and sle_y to the next position
21502 {
21503
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 50 times.
128 if(random)
21504 {
21505
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 40 times.
78 if(zc_oldrand()%2)
21506 {
21507 38 sle_x = (zc_oldrand()%2) ? 0 : 240;
21508 38 sle_y = (zc_oldrand()%10)*16;
21509 38 }
21510 else
21511 {
21512 40 sle_y = (zc_oldrand()%2) ? 0 : 160;
21513 40 sle_x = (zc_oldrand()%15)*16;
21514 }
21515
21516 78 return;
21517 }
21518
21519
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 22 times.
50 if(sle_x==0)
21520 {
21521
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2 times.
22 if(sle_y<160)
21522 20 sle_y+=16;
21523 else
21524 2 sle_x+=16;
21525 22 }
21526
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
28 else if(sle_y==160)
21527 {
21528
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 1 times.
24 if(sle_x<240)
21529 23 sle_x+=16;
21530 else
21531 1 sle_y-=16;
21532 24 }
21533
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 else if(sle_x==240)
21534 {
21535
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(sle_y>0)
21536 4 sle_y-=16;
21537 else
21538 sle_x-=16;
21539 4 }
21540 else if(sle_y==0)
21541 {
21542 if(sle_x>0)
21543 sle_x-=16;
21544 else
21545 sle_y+=16;
21546 }
21547 128 }
21548
21549 30 int32_t next_side_pos(bool random)
21550 // moves sle_x and sle_y to the next available position
21551 // returns the direction the enemy should face
21552 {
21553 bool blocked;
21554 30 int32_t c=0;
21555
21556 30 do
21557 {
21558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 nsp(c>35 ? false : random);
21559
3/4
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
158 blocked = _walkflag(sle_x,sle_y,2) || _walkflag(sle_x,sle_y+8,2) ||
21560
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 (combo_class_buf[COMBOTYPE(sle_x,sle_y)].block_enemies ||
21561
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 MAPFLAG(sle_x,sle_y) == mfNOENEMY || MAPCOMBOFLAG(sle_x,sle_y)==mfNOENEMY ||
21562
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
30 MAPFLAG(sle_x,sle_y) == mfNOGROUNDENEMY || MAPCOMBOFLAG(sle_x,sle_y)==mfNOGROUNDENEMY ||
21563 30 iswaterex(MAPCOMBO(sle_x,sle_y), currmap, currscr, -1, sle_x, sle_y, true));
21564
21565
1/2
✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
128 if(++c>50)
21566 return -1;
21567
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 30 times.
128 }
21568 128 while(blocked);
21569
21570 30 int32_t dir=0;
21571
21572
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 9 times.
30 if(sle_x==0) dir=right;
21573
21574
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 1 times.
30 if(sle_y==0) dir=down;
21575
21576
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 if(sle_x==240) dir=left;
21577
21578
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if(sle_y==168) dir=up;
21579
21580 30 return dir;
21581 30 }
21582
21583 bool can_side_load(int32_t id)
21584 {
21585 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
21586 {
21587 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "can_side_load()");
21588 return false;
21589 }
21590 switch(guysbuf[id].family) //id&0x0FFF)
21591 {
21592 //case eTEK1:
21593 //case eTEK2:
21594 //case eTEK3:
21595 //case eLEV1:
21596 //case eLEV2:
21597 //case eLEV3:
21598 //case eRAQUAM:
21599 //case eLAQUAM:
21600 //case eDODONGO:
21601 //case eMANHAN:
21602 //case eGLEEOK1:
21603 //case eGLEEOK2:
21604 //case eGLEEOK3:
21605 //case eGLEEOK4:
21606 //case eDIG1:
21607 //case eDIG3:
21608 //case eGOHMA1:
21609 //case eGOHMA2:
21610 //case eCENT1:
21611 //case eCENT2:
21612 //case ePATRA1:
21613 //case ePATRA2:
21614 //case eGANON:
21615 //case eMANHAN2:
21616 //case eCEILINGM: later
21617 //case eFLOORM: later
21618 //case ePATRABS:
21619 //case ePATRAL2:
21620 //case ePATRAL3:
21621 //case eGLEEOK1F:
21622 //case eGLEEOK2F:
21623 //case eGLEEOK3F:
21624 //case eGLEEOK4F:
21625 //case eDODONGOBS:
21626 //case eDODONGOF:
21627 //case eGOHMA3:
21628 //case eGOHMA4:
21629 //case eSHOOTMAGIC:
21630 //case eSHOOTROCK:
21631 //case eSHOOTSPEAR:
21632 //case eSHOOTSWORD:
21633 //case eSHOOTFLAME:
21634 //case eSHOOTFLAME2:
21635 //case eSHOOTFBALL:
21636 case eeTEK:
21637 case eeLEV:
21638 case eeAQUA:
21639 case eeDONGO:
21640 case eeMANHAN:
21641 case eeGLEEOK:
21642 case eeDIG:
21643 case eeGHOMA:
21644 case eeLANM:
21645 case eePATRA:
21646 case eeGANON:
21647 case eePROJECTILE:
21648 return false;
21649 break;
21650 }
21651
21652 return true;
21653 }
21654
21655 static bool script_sle = false;
21656 static int32_t sle_pattern = 0;
21657 void script_side_load_enemies()
21658 {
21659 if(script_sle || sle_clk) return;
21660 sle_cnt = 0;
21661 while(sle_cnt<10 && tmpscr->enemy[sle_cnt]!=0)
21662 ++sle_cnt;
21663 script_sle = true;
21664 sle_pattern = tmpscr->pattern;
21665 sle_clk = 0;
21666 }
21667
21668 671 void side_load_enemies()
21669 {
21670
3/4
✓ Branch 0 taken 671 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 664 times.
✓ Branch 3 taken 7 times.
671 if(!script_sle && sle_clk==0)
21671 {
21672 7 sle_pattern = tmpscr->pattern;
21673 7 sle_cnt = 0;
21674 7 int32_t guycnt = 0;
21675 7 int16_t s = (currmap<<7)+currscr;
21676 7 bool beenhere=false;
21677 7 bool reload=true;
21678 7 bool unbeatablereload = true;
21679
21680 7 load_default_enemies();
21681
21682
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 7 times.
49 for(int32_t i=0; i<6; i++)
21683
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 if(visited[i]==s)
21684 beenhere=true;
21685
21686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if(!beenhere)
21687 {
21688 7 visited[vhead]=s;
21689 7 vhead = (vhead+1)%6;
21690 7 }
21691 else if(game->guys[s]==0)
21692 {
21693 sle_cnt=0;
21694 reload=false;
21695 }
21696
21697
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if(reload)
21698 {
21699 7 sle_cnt = game->guys[s];
21700
21701
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if((get_bit(quest_rules, qr_NO_LEAVE_ONE_ENEMY_ALIVE_TRICK) && !beenhere)
21702
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
7 || sle_cnt==0)
21703 {
21704
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 7 times.
35 while(sle_cnt<10 && tmpscr->enemy[sle_cnt]!=0)
21705 28 ++sle_cnt;
21706 7 }
21707
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 if (!beenhere && get_bit(quest_rules, qr_UNBEATABLES_DONT_KEEP_DEAD))
21708 {
21709 for(int32_t i = 0; i<sle_cnt && tmpscr->enemy[i]>0; i++)
21710 {
21711 if (!(guysbuf[tmpscr->enemy[i]].flags & guy_doesntcount))
21712 {
21713 unbeatablereload = false;
21714 }
21715 }
21716 if (unbeatablereload)
21717 {
21718 while(sle_cnt<10 && tmpscr->enemy[sle_cnt]!=0)
21719 {
21720 ++sle_cnt;
21721 }
21722 }
21723 }
21724 7 }
21725
21726
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 if((get_bit(quest_rules,qr_ALWAYSRET)) || (tmpscr->flags3&fENEMIESRETURN))
21727 {
21728 sle_cnt = 0;
21729
21730 while(sle_cnt<10 && tmpscr->enemy[sle_cnt]!=0)
21731 ++sle_cnt;
21732 }
21733
21734
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 7 times.
35 for(int32_t i=0; i<sle_cnt; i++)
21735 28 ++guycnt;
21736
21737 7 game->guys[s] = guycnt;
21738 7 }
21739
21740
2/2
✓ Branch 0 taken 641 times.
✓ Branch 1 taken 30 times.
671 if((++sle_clk+8)%24 == 0)
21741 {
21742 30 int32_t dir = next_side_pos(sle_pattern==pSIDESR);
21743
21744
3/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 27 times.
30 if(dir==-1 || tooclose(sle_x,sle_y,32))
21745 {
21746 3 return;
21747 }
21748
21749 27 int32_t enemy_slot=guys.Count();
21750
21751
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
27 while(sle_cnt > 0 && !ok2add(tmpscr->enemy[sle_cnt-1]))
21752 sle_cnt--;
21753
21754
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if(sle_cnt > 0)
21755 {
21756
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if(addenemy(sle_x,sle_y,tmpscr->enemy[--sle_cnt],0))
21757 {
21758
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if (((enemy*)guys.spr(enemy_slot))->family != eeTEK)
21759 {
21760 27 guys.spr(enemy_slot)->dir = dir;
21761 27 }
21762 27 }
21763 27 }
21764 27 }
21765
21766
2/2
✓ Branch 0 taken 662 times.
✓ Branch 1 taken 6 times.
668 if(sle_cnt<=0)
21767 {
21768
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(script_sle)
21769 script_sle = false;
21770 6 else loaded_enemies=true;
21771 6 sle_clk = 0;
21772 6 }
21773 671 }
21774
21775 26034 bool is_starting_pos(int32_t i, int32_t x, int32_t y, int32_t t)
21776 {
21777
21778
4/4
✓ Branch 0 taken 23640 times.
✓ Branch 1 taken 2394 times.
✓ Branch 2 taken 2394 times.
✓ Branch 3 taken 26034 times.
26034 if(tmpscr->enemy[i]<1||tmpscr->enemy[i]>=MAXGUYS) //Hackish fix for crash in Waterford.st on screen 0x65 of dmap 0 (map 1).
21779 {
21780 //zprint2("is_starting_pos(), tmpscr->enemy[i] is: %d\n", tmpscr->enemy[i]);
21781 4788 return false; //never 0, never OoB.
21782 }
21783 // No corner enemies
21784
6/6
✓ Branch 0 taken 22177 times.
✓ Branch 1 taken 3857 times.
✓ Branch 2 taken 931 times.
✓ Branch 3 taken 23108 times.
✓ Branch 4 taken 2660 times.
✓ Branch 5 taken 2128 times.
26034 if((x==0 || x==240) && (y==0 || y==160))
21785
21786 4788 return false;
21787
21788 //Is a no spawn combo...
21789
2/4
✓ Branch 0 taken 23108 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 23108 times.
23108 if(MAPFLAG(x+8,y+8)==mfNOENEMYSPAWN || MAPCOMBOFLAG(x+8,y+8)==mfNOENEMYSPAWN)
21790 return false;
21791
21792 // No enemies in dungeon walls
21793
10/10
✓ Branch 0 taken 15948 times.
✓ Branch 1 taken 7160 times.
✓ Branch 2 taken 14108 times.
✓ Branch 3 taken 1840 times.
✓ Branch 4 taken 12268 times.
✓ Branch 5 taken 1840 times.
✓ Branch 6 taken 10060 times.
✓ Branch 7 taken 2208 times.
✓ Branch 8 taken 2208 times.
✓ Branch 9 taken 7852 times.
23108 if(isdungeon() && (x<32 || x>=224 || y<32 || y>=144))
21794 8096 return false;
21795
21796 // Too close
21797
3/4
✓ Branch 0 taken 1428 times.
✓ Branch 1 taken 13584 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1428 times.
15012 if(tooclose(x,y,40) && t<11)
21798 1428 return false;
21799
21800 // Can't fly onto it?
21801
4/4
✓ Branch 0 taken 2517 times.
✓ Branch 1 taken 11067 times.
✓ Branch 2 taken 902 times.
✓ Branch 3 taken 2 times.
14488 if(isflier(tmpscr->enemy[i])&&
21802
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 (flyerblocked(x+8,y+8,spw_floater,guysbuf[tmpscr->enemy[i]])||
21803
2/2
✓ Branch 0 taken 904 times.
✓ Branch 1 taken 1613 times.
2517 (_walkflag(x,y+8,2)&&!get_bit(quest_rules,qr_WALLFLIERS))))
21804 2 return false;
21805
21806 // Can't jump onto it?
21807 if
21808 (
21809
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1118 times.
14700 guysbuf[tmpscr->enemy[i]].family==eeTEK
21810
21811
2/2
✓ Branch 0 taken 1118 times.
✓ Branch 1 taken 12464 times.
13582 &&
21812 (
21813
1/2
✓ Branch 0 taken 1118 times.
✗ Branch 1 not taken.
1118 COMBOTYPE(x+8,y+8)==cNOJUMPZONE||
21814
1/2
✓ Branch 0 taken 1118 times.
✗ Branch 1 not taken.
1118 COMBOTYPE(x+8,y+8)==cNOENEMY||
21815
1/2
✓ Branch 0 taken 1118 times.
✗ Branch 1 not taken.
1118 ispitfall(x+8,y+8)||
21816
1/2
✓ Branch 0 taken 1118 times.
✗ Branch 1 not taken.
1118 MAPFLAG(x+8,y+8)==mfNOENEMY||
21817 1118 MAPCOMBOFLAG(x+8,y+8)==mfNOENEMY
21818 )
21819 )
21820 {
21821 return false;
21822 }
21823
21824 // Other off-limit combos
21825
6/6
✓ Branch 0 taken 11067 times.
✓ Branch 1 taken 2515 times.
✓ Branch 2 taken 9949 times.
✓ Branch 3 taken 1118 times.
✓ Branch 4 taken 6057 times.
✓ Branch 5 taken 3892 times.
23531 if((!isflier(tmpscr->enemy[i])&& guysbuf[tmpscr->enemy[i]].family!=eeTEK &&
21826
2/2
✓ Branch 0 taken 6057 times.
✓ Branch 1 taken 3892 times.
9949 (_walkflag(x,y+8,2) || groundblocked(x+8,y+8,guysbuf[tmpscr->enemy[i]]))) &&
21827 9949 guysbuf[tmpscr->enemy[i]].family!=eeZORA)
21828 3892 return false;
21829
21830 // Don't ever generate enemies on these combos!
21831
2/4
✓ Branch 0 taken 9690 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9690 times.
9690 if(COMBOTYPE(x+8,y+8)==cARMOS||COMBOTYPE(x+8,y+8)==cBSGRAVE)
21832 return false;
21833
21834 //BS Dodongos need at least 2 spaces.
21835
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9690 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
9690 if((guysbuf[tmpscr->enemy[i]].family==eeDONGO)&&(guysbuf[tmpscr->enemy[i]].misc10==1))
21836 {
21837 if(((x<16) ||_walkflag(x-16,y+8, 2))&&
21838 ((x>224)||_walkflag(x+16,y+8, 2))&&
21839 ((y<16) ||_walkflag(x, y-8, 2))&&
21840 ((y>144)||_walkflag(x, y+24,2)))
21841 {
21842 return false;
21843 }
21844 }
21845
21846 9690 return true;
21847 23640 }
21848
21849 630 bool is_ceiling_pattern(int32_t i)
21850 {
21851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 630 times.
630 return (i==pCEILING || i==pCEILINGR);
21852 }
21853
21854 133 int32_t placeenemy(int32_t i)
21855 {
21856 133 std::map<int32_t, int32_t> freeposcache;
21857 133 int32_t frees = 0;
21858
21859
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 133 times.
1596 for(int32_t y=0; y<176; y+=16)
21860 {
21861
2/2
✓ Branch 0 taken 23408 times.
✓ Branch 1 taken 1463 times.
24871 for(int32_t x=0; x<256; x+=16)
21862 {
21863
3/4
✓ Branch 0 taken 23408 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9508 times.
✓ Branch 3 taken 13900 times.
23408 if(is_starting_pos(i,x,y,0))
21864 {
21865
1/2
✓ Branch 0 taken 9508 times.
✗ Branch 1 not taken.
9508 freeposcache[frees++] = (y&0xF0)+(x>>4);
21866 9508 }
21867 23408 }
21868 1463 }
21869
21870
1/2
✓ Branch 0 taken 133 times.
✗ Branch 1 not taken.
133 if(frees > 0)
21871
2/4
✓ Branch 0 taken 133 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 133 times.
✗ Branch 3 not taken.
133 return freeposcache[zc_oldrand()%frees];
21872
21873 return -1;
21874 133 }
21875
21876 315 void spawnEnemy(int& pos, int& clk, int& x, int& y, int& fastguys, int& i, int& guycnt, int& loadcnt)
21877 {
21878 315 bool placed=false;
21879 315 int32_t t=-1;
21880
21881 // First: enemy combo flags
21882
2/2
✓ Branch 0 taken 3465 times.
✓ Branch 1 taken 315 times.
3780 for(int32_t sy=0; sy<176; sy+=16)
21883 {
21884
2/2
✓ Branch 0 taken 55440 times.
✓ Branch 1 taken 3465 times.
58905 for(int32_t sx=0; sx<256; sx+=16)
21885 {
21886 55440 int32_t cflag = MAPFLAG(sx, sy);
21887 55440 int32_t cflag_i = MAPCOMBOFLAG(sx, sy);
21888
21889
2/4
✓ Branch 0 taken 55440 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 55440 times.
✗ Branch 3 not taken.
55440 if(((cflag==mfENEMYALL)||(cflag_i==mfENEMYALL)) && (!placed))
21890 {
21891 if(!ok2add(tmpscr->enemy[i]))
21892 {
21893 if (loadcnt < 10 && tmpscr->enemy[i] > 0 && tmpscr->enemy[i] < MAXGUYS) ++loadcnt;
21894 }
21895 else
21896 {
21897 addenemy(sx,
21898 (is_ceiling_pattern(tmpscr->pattern) && isSideViewGravity()) ? -(150+50*guycnt) : sy,
21899 (is_ceiling_pattern(tmpscr->pattern) && !(isSideViewGravity())) ? 150+50*guycnt : 0,tmpscr->enemy[i],-15);
21900
21901 ++guycnt;
21902
21903 placed=true;
21904 goto placed_enemy;
21905 }
21906 }
21907
21908
2/4
✓ Branch 0 taken 55440 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 55440 times.
✗ Branch 3 not taken.
55440 else if(((cflag==mfENEMY0+i)||(cflag_i==mfENEMY0+i)) && (!placed))
21909 {
21910 if(!ok2add(tmpscr->enemy[i]))
21911 {
21912 if (loadcnt < 10 && tmpscr->enemy[i] > 0 && tmpscr->enemy[i] < MAXGUYS) ++loadcnt;
21913 }
21914 else
21915 {
21916 addenemy(sx,
21917 (is_ceiling_pattern(tmpscr->pattern) && isSideViewGravity()) ? -(150+50*guycnt) : sy,
21918 (is_ceiling_pattern(tmpscr->pattern) && !(isSideViewGravity())) ? 150+50*guycnt : 0,tmpscr->enemy[i],-15);
21919
21920 ++guycnt;
21921
21922 placed=true;
21923 goto placed_enemy;
21924 }
21925 }
21926 55440 }
21927 3465 }
21928
21929 // Next: enemy pattern
21930
6/8
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 182 times.
✓ Branch 2 taken 182 times.
✓ Branch 3 taken 133 times.
✓ Branch 4 taken 182 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 182 times.
315 if((tmpscr->pattern==pRANDOM || tmpscr->pattern==pCEILING) && !(isSideViewGravity()) && ((tmpscr->enemy[i]>0&&tmpscr->enemy[i]<MAXGUYS)))
21931 {
21932 182 do
21933 {
21934
21935 // NES positions
21936 232 pos%=9;
21937 232 x=stx[loadside][pos];
21938 232 y=sty[loadside][pos];
21939 232 ++pos;
21940 232 ++t;
21941
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 182 times.
414 }
21942
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 232 times.
232 while((t< 20) && !is_starting_pos(i,x,y,t));
21943 182 }
21944
21945
3/4
✓ Branch 0 taken 182 times.
✓ Branch 1 taken 133 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 182 times.
315 if(t<0 || t >= 20) // above enemy pattern failed
21946 {
21947 // Final chance: find a random position anywhere onscreen
21948 133 int32_t randpos = placeenemy(i);
21949
21950
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 133 times.
133 if(randpos>-1)
21951 {
21952 133 x=(randpos&15)<<4;
21953 133 y= randpos&0xF0;
21954 133 }
21955 else // All opportunities failed - abort
21956 {
21957 return;
21958 }
21959 133 }
21960
21961 {
21962 315 int32_t c=0;
21963 315 c=clk;
21964
21965
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 232 times.
315 if(!slowguy(tmpscr->enemy[i]))
21966 232 ++fastguys;
21967
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 72 times.
83 else if(fastguys>0)
21968 11 c=-15*(i-fastguys+2);
21969 else
21970 72 c=-15*(i+1);
21971
21972
4/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 305 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
315 if(BSZ&&((tmpscr->enemy[i]>0&&tmpscr->enemy[i]<MAXGUYS))) // Hackish fix for crash in Waterford.qst on screen 0x65 of dmap 0 (map 1).
21973 {
21974 // Special case for blue leevers
21975
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if(guysbuf[tmpscr->enemy[i]].family==eeLEV && guysbuf[tmpscr->enemy[i]].misc1==1)
21976 c=-15*(i+1);
21977 else
21978 10 c=-15;
21979 10 }
21980
21981
1/2
✓ Branch 0 taken 315 times.
✗ Branch 1 not taken.
315 if(!ok2add(tmpscr->enemy[i]))
21982 {
21983 if (loadcnt < 10 && tmpscr->enemy[i] > 0 && tmpscr->enemy[i] < MAXGUYS) ++loadcnt;
21984 }
21985 else
21986 {
21987
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 315 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
315 if(((tmpscr->enemy[i]>0||tmpscr->enemy[i]<MAXGUYS))) // Hackish fix for crash in Waterford.qst on screen 0x65 of dmap 0 (map 1).
21988 {
21989
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 315 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
630 addenemy(x,(is_ceiling_pattern(tmpscr->pattern) && isSideViewGravity()) ? -(150+50*guycnt) : y,
21990
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 315 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
315 (is_ceiling_pattern(tmpscr->pattern) && !(isSideViewGravity())) ? 150+50*guycnt : 0,tmpscr->enemy[i],c);
21991
21992 315 ++guycnt;
21993 315 }
21994 }
21995
21996 315 placed=true;
21997 315 } // if(t < 20)
21998
21999 placed_enemy:
22000
22001 // I don't like this, but it seems to work...
22002 static bool foundCarrier;
22003
22004
2/2
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 71 times.
315 if(i==0)
22005 71 foundCarrier=false;
22006
22007
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 315 times.
315 if(placed)
22008 {
22009
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 244 times.
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
315 if(i==0 && tmpscr->enemyflags&efLEADER)
22010 {
22011 int32_t index = guys.idFirst(tmpscr->enemy[i],0xFFF);
22012
22013 if(index!=-1)
22014 {
22015 //grab the first segment. Not accurate to how older versions did it, but the way they did it might be incompatible with enemy editor.
22016 if ((((enemy*)guys.spr(index))->family == eeLANM) && !get_bit(quest_rules, qr_NO_LANMOLA_RINGLEADER)) index = guys.idNth(tmpscr->enemy[i], 2, 0xFFF);
22017 if(index!=-1)
22018 {
22019 ((enemy*)guys.spr(index))->leader = true;
22020 }
22021 }
22022 }
22023
22024
4/4
✓ Branch 0 taken 303 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 300 times.
✓ Branch 3 taken 3 times.
315 if(!foundCarrier && hasitem&(4|2))
22025 {
22026 3 int32_t index = guys.idFirst(tmpscr->enemy[i],0xFFF);
22027
22028
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if(index!=-1 && (((enemy*)guys.spr(index))->flags&guy_doesntcount)==0)
22029 {
22030 3 ((enemy*)guys.spr(index))->itemguy = true;
22031 3 foundCarrier=true;
22032 3 }
22033 3 }
22034 315 }
22035 315 }
22036
22037 bool scriptloadenemies()
22038 {
22039 loaded_enemies = true;
22040 if(script_sle || sle_clk) return false;
22041 if(tmpscr->pattern==pNOSPAWN) return false;
22042
22043 if(tmpscr->pattern==pSIDES || tmpscr->pattern==pSIDESR)
22044 {
22045 script_side_load_enemies();
22046 return true;
22047 }
22048
22049 int32_t pos=zc_oldrand()%9;
22050 int32_t clk=-15,x=0,y=0,fastguys=0;
22051 int32_t i=0,guycnt=0;
22052 int32_t loadcnt = 10;
22053
22054 for(; i<loadcnt && tmpscr->enemy[i]>0; i++)
22055 {
22056 spawnEnemy(pos, clk, x, y, fastguys, i, guycnt, loadcnt);
22057
22058 --clk;
22059 }
22060 return true;
22061 }
22062
22063 68617 void loadenemies()
22064 {
22065
3/4
✓ Branch 0 taken 68617 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 664 times.
✓ Branch 3 taken 67953 times.
68617 if(script_sle || sle_clk)
22066 {
22067 664 side_load_enemies();
22068 664 return;
22069 }
22070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 67953 times.
67953 if(tmpscr->pattern==pNOSPAWN) return;
22071
2/2
✓ Branch 0 taken 67798 times.
✓ Branch 1 taken 155 times.
67953 if(loaded_enemies)
22072 67798 return;
22073
22074 // check if it's the dungeon boss and it has been beaten before
22075
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 153 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
155 if(tmpscr->enemyflags&efBOSS && game->lvlitems[dlevel]&liBOSS)
22076 {
22077 loaded_enemies = true;
22078 return;
22079 }
22080
22081
4/4
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 148 times.
155 if(tmpscr->pattern==pSIDES || tmpscr->pattern==pSIDESR)
22082 {
22083 7 side_load_enemies();
22084 7 return;
22085 }
22086
22087 148 loaded_enemies=true;
22088
22089 // do enemies that are always loaded
22090 148 load_default_enemies();
22091
22092 // dungeon basements
22093
22094 static byte dngn_enemy_x[4] = {32,96,144,208};
22095
22096
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 136 times.
148 if(currscr>=128)
22097 {
22098
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2 times.
12 if(DMaps[currdmap].flags&dmfCAVES) return;
22099
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if ( DMaps[currdmap].flags&dmfNEWCELLARENEMIES )
22100 {
22101 for(int32_t i=0; i<10; i++)
22102 {
22103 if ( tmpscr->enemy[i] )
22104 {
22105 addenemy(dngn_enemy_x[i],96,tmpscr->enemy[i],-14-i);
22106 }
22107 }
22108 }
22109 else
22110 {
22111
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 for(int32_t i=0; i<4; i++)
22112
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 addenemy(dngn_enemy_x[i],96,tmpscr->enemy[i]?tmpscr->enemy[i]:(int32_t)eKEESE1,-14-i);
22113 }
22114 2 return;
22115 }
22116
22117 // check if it's been long enough to reload all enemies
22118
22119 136 int32_t loadcnt = 10;
22120 136 int16_t s = (currmap<<7)+currscr;
22121 136 bool beenhere = false;
22122 136 bool reload = true;
22123 136 bool unbeatablereload = true;
22124
22125
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 136 times.
952 for(int32_t i=0; i<6; i++)
22126
2/2
✓ Branch 0 taken 781 times.
✓ Branch 1 taken 35 times.
851 if(visited[i]==s)
22127 35 beenhere = true;
22128
22129
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 101 times.
136 if(!beenhere) //Okay so this basically checks the last 6 unique screen's you've been in and checks if the current screen is one of them.
22130 {
22131 101 visited[vhead]=s; //If not, it adds it to the array,
22132 101 vhead = (vhead+1)%6; //which overrides one of the others, and then moves onto the next.
22133 101 }
22134
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 32 times.
35 else if(game->guys[s]==0) //Then, if you have been here, and the number of enemies left on the screen is 0,
22135 {
22136 32 loadcnt = 0; //It will tell it not to load any enemies,
22137 32 reload = false; //both by setting loadcnt to 0 and making the reload if statement not run.
22138 32 }
22139
22140
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 104 times.
136 if(reload) //This if statement is only false if this screen is one of the last 6 screens you visited and you left 0 enemies alive.
22141 {
22142 104 loadcnt = game->guys[s]; //Otherwise, if this if statement is true, it will try to load the last amount of enemies you left alive.
22143
22144
2/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
104 if(loadcnt==0 || //Then, if the number of enemies is 0, that means you left 0 enemies alive on a screen but haven't been there in the past 6 screens.
22145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 (get_bit(quest_rules, qr_NO_LEAVE_ONE_ENEMY_ALIVE_TRICK) && !beenhere)) //Alternatively, if you have the quest rule enabled that always respawns all enemies after a period of time, and you haven't been here in 6 screens.
22146 100 loadcnt = 10; //That means all enemies need to be respawned.
22147
3/4
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 101 times.
✗ Branch 3 not taken.
104 if (!beenhere && get_bit(quest_rules, qr_UNBEATABLES_DONT_KEEP_DEAD))
22148 {
22149 for(int32_t i = 0; i<loadcnt && tmpscr->enemy[i]>0; i++)
22150 {
22151 if (!(guysbuf[tmpscr->enemy[i]].flags & guy_doesntcount))
22152 {
22153 unbeatablereload = false;
22154 }
22155 }
22156 if (unbeatablereload)
22157 {
22158 loadcnt = 10;
22159 }
22160 }
22161 104 }
22162
22163
3/4
✓ Branch 0 taken 136 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 135 times.
136 if((get_bit(quest_rules,qr_ALWAYSRET)) || (tmpscr->flags3&fENEMIESRETURN)) //If enemies always return is enabled quest-wide or for this screen,
22164 1 loadcnt = 10; //All enemies also need to be respawned.
22165
22166 136 int32_t pos=zc_oldrand()%9; //This sets up a variable for spawnEnemy to edit so as to spawn the enemies pseudo-randomly.
22167 136 int32_t clk=-15,x=0,y=0,fastguys=0; //clk being negative means the enemy is in it's spawn poof.
22168 136 int32_t i=0,guycnt=0; //Lastly, resets guycnt to 0 so spawnEnemy can increment it manually per-enemy.
22169
22170
4/4
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 413 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 136 times.
451 for(; i<loadcnt && tmpscr->enemy[i]>0; i++)
22171 {
22172 315 spawnEnemy(pos, clk, x, y, fastguys, i, guycnt, loadcnt);
22173
22174 315 --clk; //Each additional enemy spawns with a slightly longer spawn poof than the previous.
22175 315 }
22176
22177 136 game->guys[s] = guycnt;
22178 //} //if(true)
22179 68617 }
22180 3 void moneysign()
22181 {
22182 3 additem(48,108,iRupy,ipDUMMY);
22183 // textout(scrollbuf,zfont,"X",64,112,CSET(0)+1);
22184 3 set_clip_state(pricesdisplaybuf, 0);
22185 3 textout_ex(pricesdisplaybuf,zfont,"X",64,112,CSET(0)+1,-1);
22186 3 }
22187
22188 16 void putprices(bool sign)
22189 {
22190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if(fadeclk > 0) return;
22191 // refresh what's under the prices
22192 // for(int32_t i=5; i<12; i++)
22193 // putcombo(scrollbuf,i<<4,112,tmpscr->data[112+i],tmpscr->cpage);
22194
22195 16 rectfill(pricesdisplaybuf, 72, 112, pricesdisplaybuf->w-1, pricesdisplaybuf->h-1, 0);
22196 16 int32_t step=32;
22197 16 int32_t x=80;
22198
22199
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
16 if(prices[2]==0)
22200 {
22201 10 step<<=1;
22202
22203
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(prices[1]==0)
22204 {
22205 10 x=112;
22206 10 }
22207 10 }
22208
22209
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 48 times.
64 for(int32_t i=0; i<3; i++)
22210 {
22211 // Kind of stupid, but it works: 100000 is used to indicate that an item
22212 // has a price of zero rather than there being no item.
22213 // 100000 isn't a valid price, so this doesn't cause problems.
22214
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
48 if(prices[i]!=0 && prices[i]<100000)
22215 {
22216 char buf[8];
22217 18 sprintf(buf,sign?"%+3d":"%3d",prices[i]);
22218
22219 18 int32_t l=(int32_t)strlen(buf);
22220 18 set_clip_state(pricesdisplaybuf, 0);
22221
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 textout_ex(pricesdisplaybuf,zfont,buf,x-(l>3?(l-3)<<3:0),112,CSET(0)+1,-1);
22222 18 }
22223
22224 48 x+=step;
22225 48 }
22226 16 }
22227
22228 // Setting up special rooms
22229 // Also called when the Letter is used successfully.
22230 13 void setupscreen()
22231 {
22232 13 boughtsomething=false;
22233 13 int32_t t=currscr<128?0:1;
22234 13 word str=tmpscr[t].str;
22235
22236 // Prices are already set to 0 in dowarp()
22237
3/15
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
13 switch(tmpscr[t].room)
22238 {
22239 case rSP_ITEM: // special item
22240 7 additem(120,89,tmpscr[t].catchall,ipONETIME2+ipHOLDUP+ipCHECK | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0));
22241 7 break;
22242
22243 case rINFO: // pay for info
22244 {
22245 int32_t count = 0;
22246 int32_t base = 88;
22247 int32_t step = 5;
22248
22249 moneysign();
22250
22251 for(int32_t i=0; i<3; i++)
22252 {
22253 if(QMisc.info[tmpscr[t].catchall].str[i])
22254 {
22255 ++count;
22256 }
22257 else
22258 break;
22259 }
22260
22261 if(count)
22262 {
22263 if(count==1)
22264 {
22265 base = 88+32;
22266 }
22267
22268 if(count==2)
22269 {
22270 step = 6;
22271 }
22272
22273 for(int32_t i=0; i < count; i++)
22274 {
22275 additem((i << step)+base, 89, iRupy, ipMONEY + ipDUMMY);
22276 ((item*)items.spr(items.Count()-1))->PriceIndex = i;
22277 prices[i] = -(QMisc.info[tmpscr[t].catchall].price[i]);
22278 if(prices[i]==0)
22279 prices[i]=100000; // So putprices() knows there's an item here and positions the price correctly
22280 int32_t itemid = current_item_id(itype_wealthmedal);
22281
22282 if(itemid>=0 && prices[i]!=100000)
22283 {
22284 if(itemsbuf[itemid].flags & ITEM_FLAG1)
22285 prices[i]=((prices[i]*itemsbuf[itemid].misc1)/100);
22286 else
22287 prices[i]-=itemsbuf[itemid].misc1;
22288 prices[i]=vbound(prices[i], -99999, 0);
22289 if(prices[i]==0)
22290 prices[i]=100000;
22291 }
22292
22293 if((QMisc.info[tmpscr[t].catchall].price[i])>1 && prices[i]>-1 && prices[i]!=100000)
22294 prices[i]=-1;
22295 }
22296 }
22297
22298 break;
22299 }
22300
22301 case rMONEY: // secret money
22302 additem(120,89,iRupy,ipONETIME+ipDUMMY+ipMONEY);
22303 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22304 break;
22305
22306 case rGAMBLE: // gambling
22307 prices[0]=prices[1]=prices[2]=-10;
22308 moneysign();
22309 additem(88,89,iRupy,ipMONEY+ipDUMMY);
22310 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22311 additem(120,89,iRupy,ipMONEY+ipDUMMY);
22312 ((item*)items.spr(items.Count()-1))->PriceIndex = 1;
22313 additem(152,89,iRupy,ipMONEY+ipDUMMY);
22314 ((item*)items.spr(items.Count()-1))->PriceIndex = 2;
22315 break;
22316
22317 case rREPAIR: // door repair
22318 setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
22319 // }
22320 repaircharge=tmpscr[t].catchall;
22321 break;
22322
22323 case rMUPGRADE: // upgrade magic
22324 adjustmagic=true;
22325 break;
22326
22327 case rLEARNSLASH: // learn slash attack
22328 learnslash=true;
22329 break;
22330
22331 case rRP_HC: // heart container or red potion
22332 additem(88,89,iRPotion,ipONETIME2+ipHOLDUP+ipFADE);
22333 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22334 additem(152,89,iHeartC,ipONETIME2+ipHOLDUP+ipFADE);
22335 ((item*)items.spr(items.Count()-1))->PriceIndex = 1;
22336 break;
22337
22338 case rP_SHOP: // potion shop
22339 if(current_item(itype_letter)<i_letter_used)
22340 {
22341 str=0;
22342 break;
22343 }
22344
22345 [[fallthrough]];
22346 case rTAKEONE: // take one
22347 case rSHOP: // shop
22348 {
22349 3 int32_t count = 0;
22350 3 int32_t base = 88;
22351 3 int32_t step = 5;
22352
22353
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(tmpscr[t].room != rTAKEONE)
22354 3 moneysign();
22355
22356 //count and align the stuff
22357
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 9 times.
12 for(int32_t i=0; i<3; ++i)
22358 {
22359
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if(QMisc.shop[tmpscr[t].catchall].hasitem[count] != 0)
22360 {
22361 9 ++count;
22362 9 }
22363 else
22364 {
22365 break;
22366 }
22367 9 }
22368
22369
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(count==1)
22370 {
22371 base = 88+32;
22372 }
22373
22374
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(count==2)
22375 {
22376 step = 6;
22377 }
22378
22379
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 for(int32_t i=0; i<count; i++)
22380 {
22381 9 additem((i<<step)+base, 89, QMisc.shop[tmpscr[t].catchall].item[i], ipHOLDUP+ipFADE+(tmpscr[t].room == rTAKEONE ? ipONETIME2 : ipCHECK));
22382 9 ((item*)items.spr(items.Count()-1))->PriceIndex = i;
22383
22384
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if(tmpscr[t].room != rTAKEONE)
22385 {
22386 9 prices[i] = QMisc.shop[tmpscr[t].catchall].price[i];
22387
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if(prices[i]==0)
22388 prices[i]=100000; // So putprices() knows there's an item here and positions the price correctly
22389 9 int32_t itemid = current_item_id(itype_wealthmedal);
22390
22391
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
9 if(itemid>=0 && prices[i]!=100000)
22392 {
22393 if(itemsbuf[itemid].flags & ITEM_FLAG1)
22394 prices[i]=((prices[i]*itemsbuf[itemid].misc1)/100);
22395 else
22396 prices[i]+=itemsbuf[itemid].misc1;
22397 prices[i]=vbound(prices[i], 0, 99999);
22398 if(prices[i]==0)
22399 prices[i]=100000;
22400 }
22401
22402
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 if((QMisc.shop[tmpscr[t].catchall].price[i])>1 && prices[i]<1)
22403 prices[i]=1;
22404 9 }
22405 9 }
22406
22407 3 break;
22408 }
22409 case rBOTTLESHOP: // bottle shop
22410 {
22411 int32_t count = 0;
22412 int32_t base = 88;
22413 int32_t step = 5;
22414
22415 moneysign();
22416 bottleshoptype const& bst = QMisc.bottle_shop_types[tmpscr[t].catchall];
22417 //count and align the stuff
22418 for(int32_t i=0; i<3; ++i)
22419 {
22420 if(bst.fill[count] != 0)
22421 {
22422 ++count;
22423 }
22424 else
22425 {
22426 break;
22427 }
22428 }
22429
22430 if(count==1)
22431 {
22432 base = 88+32;
22433 }
22434
22435 if(count==2)
22436 {
22437 step = 6;
22438 }
22439
22440 for(int32_t i=0; i<count; i++)
22441 {
22442 adddummyitem((i<<step)+base, 89, /*Use item 0 as a dummy...*/0, ipHOLDUP+ipFADE+ipCHECK);
22443 //{ Setup dummy item
22444 item* curItem = ((item*)items.spr(items.Count()-1));
22445 curItem->PriceIndex = i;
22446 newcombo const& cmb = combobuf[bst.comb[i]];
22447 curItem->o_tile = cmb.o_tile;
22448 curItem->o_cset = bst.cset[i];
22449 curItem->cs = curItem->o_cset;
22450 curItem->tile = cmb.o_tile;
22451 curItem->o_speed = cmb.speed;
22452 curItem->o_delay = 0;
22453 curItem->frames = cmb.frames;
22454 curItem->flip = cmb.flip;
22455 curItem->family = itype_bottlefill; //no pickup w/o empty bottle
22456 curItem->pstring = 0;
22457 curItem->pickup = ipHOLDUP+ipFADE+ipCHECK;
22458 curItem->flash = false;
22459 curItem->twohand = false;
22460 curItem->anim = true;
22461 curItem->hxsz=1;
22462 curItem->hyofs=4;
22463 curItem->hysz=12;
22464 curItem->script=0;
22465 curItem->txsz=1;
22466 curItem->tysz=1;
22467 //}
22468
22469 prices[i] = bst.price[i];
22470 if(prices[i]==0)
22471 prices[i]=100000; // So putprices() knows there's an item here and positions the price correctly
22472 int32_t itemid = current_item_id(itype_wealthmedal);
22473
22474 if(itemid>=0 && prices[i]!=100000)
22475 {
22476 if(itemsbuf[itemid].flags & ITEM_FLAG1)
22477 prices[i]=((prices[i]*itemsbuf[itemid].misc1)/100);
22478 else
22479 prices[i]+=itemsbuf[itemid].misc1;
22480 prices[i]=vbound(prices[i], 0, 99999);
22481 if(prices[i]==0)
22482 prices[i]=100000;
22483 }
22484
22485 if((bst.price[i])>1 && prices[i]<1)
22486 prices[i]=1;
22487 }
22488
22489 break;
22490 }
22491
22492 case rBOMBS: // more bombs
22493 additem(120,89,iRupy,ipDUMMY+ipMONEY);
22494 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22495 prices[0]=-tmpscr[t].catchall;
22496 break;
22497
22498 case rARROWS: // more arrows
22499 additem(120,89,iRupy,ipDUMMY+ipMONEY);
22500 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22501 prices[0]=-tmpscr[t].catchall;
22502 break;
22503
22504 case rSWINDLE: // leave heart container or money
22505 additem(88,89,iHeartC,ipDUMMY+ipMONEY);
22506 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22507 prices[0]=-1;
22508 additem(152,89,iRupy,ipDUMMY+ipMONEY);
22509 ((item*)items.spr(items.Count()-1))->PriceIndex = 1;
22510 prices[1]=-tmpscr[t].catchall;
22511 break;
22512
22513 }
22514
22515
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
13 if(tmpscr[t].room == rBOMBS || tmpscr[t].room == rARROWS)
22516 {
22517 int32_t i = (tmpscr[t].room == rSWINDLE ? 1 : 0);
22518 int32_t itemid = current_item_id(itype_wealthmedal);
22519
22520 if(itemid >= 0)
22521 {
22522 if(itemsbuf[itemid].flags & ITEM_FLAG1)
22523 prices[i]*=(itemsbuf[itemid].misc1/100.0);
22524 else
22525 prices[i]+=itemsbuf[itemid].misc1;
22526 }
22527
22528 if(tmpscr[t].catchall>1 && prices[i]>-1)
22529 prices[i]=-1;
22530 }
22531
22532 13 putprices(false);
22533
22534
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if(str)
22535 {
22536 13 donewmsg(str);
22537 13 }
22538 else
22539 {
22540 Hero.unfreeze();
22541 }
22542 13 }
22543
22544 // Increments msgptr and returns the control code argument pointed at.
22545 word grab_next_argument()
22546 {
22547 if(unsigned(msgptr+1)>=MsgStrings[msgstr].s.size()) return 0;
22548 byte val=MsgStrings[msgstr].s[++msgptr]-1;
22549 word ret=val;
22550
22551 // If an argument is succeeded by 255, then it's a three-byte argument -
22552 // between 254 and 65535 (or whatever the maximum actually is)
22553 if((unsigned(msgptr+2)<MsgStrings[msgstr].s.size())
22554 && uint8_t(MsgStrings[msgstr].s[msgptr+1]) == 255)
22555 {
22556 val=MsgStrings[msgstr].s[msgptr+2];
22557 word next=val;
22558 ret += 254*next;
22559 msgptr+=2;
22560 }
22561
22562 return ret;
22563 }
22564
22565 enum
22566 {
22567 MNU_CURSOR_TILE, MNU_CURSOR_CSET,
22568 MNU_CURSOR_WID, MNU_CURSOR_HEI, MNU_CURSOR_FLIP,
22569
22570 MNU_CHOSEN, MNU_TIMER, MNU_CAN_CONFIRM,
22571
22572 MNU_DATA_MAX
22573 };
22574 struct menu_choice
22575 {
22576 int32_t x, y;
22577 int32_t pos;
22578 int32_t upos, dpos, lpos, rpos;
22579 menu_choice() : x(0), y(0), pos(0), upos(0), dpos(0), lpos(0), rpos(0)
22580 {}
22581 menu_choice(int32_t x, int32_t y, int32_t pos, int32_t upos,
22582 int32_t dpos, int32_t lpos, int32_t rpos)
22583 : x(x), y(y), pos(pos), upos(upos), dpos(dpos), lpos(lpos), rpos(rpos)
22584 {}
22585 };
22586 static int32_t msg_menu_data[MNU_DATA_MAX];
22587 static bool do_run_menu = false;
22588 bool do_end_str = false;
22589 static bool wait_advance = false;
22590 14 static std::map<int32_t, menu_choice> menu_options;
22591 192 void clr_msg_data()
22592 {
22593 192 do_end_str = false;
22594 192 wait_advance = false;
22595 192 do_run_menu = false;
22596 192 menu_options.clear();
22597 192 memset(msg_menu_data, 0, sizeof(msg_menu_data));
22598 192 }
22599
22600 static bool doing_name_insert = false;
22601 static char namebuf[9] = {0};
22602 static char* nameptr = NULL;
22603 static int32_t ssc_tile_hei = -1, ssc_tile_hei_buf = -1;
22604 bool runMenuCursor()
22605 {
22606 clear_bitmap(msg_menu_bmp_buf);
22607 if(!menu_options.size())
22608 {
22609 msg_menu_data[MNU_CHOSEN] = 0;
22610 return true; //end menu
22611 }
22612 int32_t pos = msg_menu_data[MNU_CHOSEN];
22613 //If the cursor is at an invalid pos, find the first pos >= 0...
22614 if(menu_options.find(pos) == menu_options.end())
22615 {
22616 pos = 0;
22617 while(menu_options.find(pos) == menu_options.end())
22618 ++pos;
22619 }
22620 menu_choice* ch = &menu_options[pos];
22621
22622 bool pressed = true;
22623 if(rUp()) pos = ch->upos;
22624 else if(rDown()) pos = ch->dpos;
22625 else if(rLeft()) pos = ch->lpos;
22626 else if(rRight()) pos = ch->rpos;
22627 else pressed = false;
22628
22629 if(pressed)
22630 msg_menu_data[MNU_TIMER] = 1;
22631
22632 bool hold_input = !((msg_menu_data[MNU_TIMER]++) % 5);
22633 bool held = false;
22634 if(hold_input)
22635 {
22636 held = true;
22637 if(Up()) pos = ch->upos;
22638 else if(Down()) pos = ch->dpos;
22639 else if(Left()) pos = ch->lpos;
22640 else if(Right()) pos = ch->rpos;
22641 else held = false;
22642 }
22643 //If the cursor is at an invalid pos, find the first pos >= 0...
22644 if(menu_options.find(pos) == menu_options.end())
22645 {
22646 pos = 0;
22647 while(menu_options.find(pos) == menu_options.end())
22648 ++pos;
22649 }
22650 if((pressed || held) && pos != msg_menu_data[MNU_CHOSEN])
22651 sfx(MsgStrings[msgstr].sfx);
22652
22653 ch = &menu_options[pos];
22654 overtileblock16(msg_menu_bmp_buf, msg_menu_data[MNU_CURSOR_TILE],
22655 ch->x, ch->y, (int32_t)ceil(msg_menu_data[MNU_CURSOR_WID]/16.0),
22656 (int32_t)ceil(msg_menu_data[MNU_CURSOR_HEI]/16.0),
22657 msg_menu_data[MNU_CURSOR_CSET], msg_menu_data[MNU_CURSOR_FLIP]);
22658
22659 msg_menu_data[MNU_CHOSEN] = pos;
22660
22661 if(!msg_menu_data[MNU_CAN_CONFIRM]) //Prevent instantly accepting when holding A
22662 {
22663 rAbtn(); //Eat
22664 if(!cAbtn()) msg_menu_data[MNU_CAN_CONFIRM] = 1;
22665 }
22666
22667 bool ret = (pressed || held) ? false : rAbtn();
22668 //Eat inputs
22669 rUp(); rDown(); rLeft(); rRight(); rAbtn();
22670
22671 if(ret)
22672 menu_options.clear();
22673
22674 return ret;
22675 //false if pos changed this frame; no confirming while moving the cursor!
22676 }
22677
22678 3504 bool bottom_margin_clip()
22679 {
22680 3804 return !get_bit(quest_rules, qr_OLD_STRING_EDITOR_MARGINS)
22681
2/2
✓ Branch 0 taken 300 times.
✓ Branch 1 taken 3204 times.
3504 && cursor_y >= (msg_h + (get_bit(quest_rules,qr_STRING_FRAME_OLD_WIDTH_HEIGHT)?16:0) - msg_margins[down]);
22682 }
22683
22684 700 bool parsemsgcode()
22685 {
22686
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 683 times.
700 if(msgptr>=MsgStrings[msgstr].s.size()) return false;
22687 683 byte c = byte(MsgStrings[msgstr].s[msgptr]-1);
22688
1/36
✗ Branch 0 not taken.
✓ Branch 1 taken 683 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
683 switch(c)
22689 {
22690 case MSGC_NEWLINE:
22691 {
22692 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
22693 ssc_tile_hei = ssc_tile_hei_buf;
22694 ssc_tile_hei_buf = -1;
22695 cursor_y += thei + MsgStrings[msgstr].vspace;
22696 cursor_x=msg_margins[left];
22697 return true;
22698 }
22699
22700 case MSGC_COLOUR:
22701 {
22702 int32_t cset = (grab_next_argument());
22703 msgcolour = CSET(cset)+(grab_next_argument());
22704 return true;
22705 }
22706
22707 case MSGC_SHDCOLOR:
22708 {
22709 int32_t cset = (grab_next_argument());
22710 msg_shdcol = CSET(cset)+(grab_next_argument());
22711 return true;
22712 }
22713 case MSGC_SHDTYPE:
22714 {
22715 msg_shdtype = grab_next_argument();
22716 return true;
22717 }
22718
22719 case MSGC_SPEED:
22720 {
22721 msgspeed=grab_next_argument();
22722 return true;
22723 }
22724
22725 case MSGC_CTRUP:
22726 {
22727 int32_t a1 = grab_next_argument();
22728 int32_t a2 = grab_next_argument();
22729 game->change_counter(a2, a1);
22730 return true;
22731 }
22732
22733 case MSGC_CTRDN:
22734 {
22735 int32_t a1 = grab_next_argument();
22736 int32_t a2 = grab_next_argument();
22737 game->change_counter(-a2, a1);
22738 return true;
22739 }
22740
22741 case MSGC_CTRSET:
22742 {
22743 int32_t a1 = grab_next_argument();
22744 int32_t a2 = grab_next_argument();
22745 game->set_counter(vbound(a2, 0, game->get_maxcounter(a1)), a1);
22746 return true;
22747 }
22748
22749 case MSGC_CTRUPPC:
22750 case MSGC_CTRDNPC:
22751 case MSGC_CTRSETPC:
22752 {
22753 int32_t code = MsgStrings[msgstr].s[msgptr]-1;
22754 int32_t counter = grab_next_argument();
22755 int32_t amount = grab_next_argument();
22756 amount = int32_t(vbound(amount*0.01, 0.0, 1.0)*game->get_maxcounter(counter));
22757
22758 if(code==MSGC_CTRDNPC)
22759 amount*=-1;
22760
22761 if(code==MSGC_CTRSETPC)
22762 game->set_counter(amount, counter);
22763 else
22764 game->change_counter(amount, counter);
22765
22766 return true;
22767 }
22768
22769 case MSGC_GIVEITEM:
22770 {
22771 int32_t itemID = grab_next_argument();
22772
22773 getitem(itemID, true);
22774 if ( !item_doscript[itemID] && (((unsigned)itemID) < 256) )
22775 {
22776 itemScriptData[itemID].Clear();
22777 memset(item_stack[itemID], 0xFFFF, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
22778 if ( (itemsbuf[itemID].flags&ITEM_PASSIVESCRIPT) ) item_doscript[itemID] = 1;
22779 }
22780 return true;
22781 }
22782
22783
22784 case MSGC_WARP:
22785 {
22786 int32_t dmap = grab_next_argument();
22787 int32_t scrn = grab_next_argument();
22788 int32_t dx = grab_next_argument();
22789 int32_t dy = grab_next_argument();
22790 int32_t wfx = grab_next_argument();
22791 int32_t sfx = grab_next_argument();
22792 if(dx >= MAX_SCC_ARG) dx = -1;
22793 if(dy >= MAX_SCC_ARG) dy = -1;
22794 FFCore.warp_player(wtIWARP, dmap, scrn, dx, dy, wfx, sfx, warpFlagDONTKILLMUSIC, 0);
22795 return true;
22796 }
22797
22798 case MSGC_SETSCREEND:
22799 {
22800 int32_t dmap = (grab_next_argument()<<7); //dmap and screen may be transposed here.
22801 int32_t screen = grab_next_argument();
22802 int32_t reg = grab_next_argument();
22803 int32_t val = grab_next_argument();
22804 FFCore.set_screen_d(screen + dmap, reg, val);
22805 return true;
22806 }
22807 case MSGC_TAKEITEM:
22808 {
22809 int32_t itemID = grab_next_argument();
22810 if ( item_doscript[itemID] )
22811 {
22812 item_doscript[itemID] = 4; //Val of 4 means 'clear stack and quit'
22813 }
22814 takeitem(itemID);
22815 if ( game->forced_bwpn == itemID )
22816 {
22817 game->forced_bwpn = -1;
22818 } //not else if! -Z
22819 if ( game->forced_awpn == itemID )
22820 {
22821 game->forced_awpn = -1;
22822 }
22823 if ( game->forced_xwpn == itemID )
22824 {
22825 game->forced_xwpn = -1;
22826 } //not else if! -Z
22827 if ( game->forced_ywpn == itemID )
22828 {
22829 game->forced_ywpn = -1;
22830 }
22831 verifyBothWeapons();
22832 return true;
22833 }
22834
22835 case MSGC_SFX:
22836 {
22837 sfx((int32_t)grab_next_argument(),128);
22838 return true;
22839 }
22840
22841 case MSGC_MIDI:
22842 {
22843 int32_t music = (int32_t)(grab_next_argument());
22844
22845 if(music==0)
22846 music_stop();
22847 else
22848 jukebox(music+(ZC_MIDI_COUNT-1));
22849
22850 return true;
22851 }
22852
22853 case MSGC_NAME:
22854 {
22855 doing_name_insert = true;
22856 sprintf(namebuf, "%s", game->get_name());
22857 nameptr = namebuf;
22858 return true;
22859 }
22860
22861 case MSGC_DRAWTILE:
22862 {
22863 int32_t tl = grab_next_argument();
22864 int32_t cs = grab_next_argument();
22865 int32_t t_wid = grab_next_argument();
22866 int32_t t_hei = grab_next_argument();
22867 int32_t fl = grab_next_argument();
22868
22869 if(cursor_x+MsgStrings[msgstr].hspace + t_wid > msg_w-msg_margins[right])
22870 {
22871 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
22872 ssc_tile_hei = ssc_tile_hei_buf;
22873 ssc_tile_hei_buf = -1;
22874 cursor_y += thei + MsgStrings[msgstr].vspace;
22875 if(bottom_margin_clip()) return true;
22876 cursor_x=msg_margins[left];
22877 }
22878
22879 overtileblock16(msg_txt_bmp_buf, tl, cursor_x, cursor_y, (int32_t)ceil(t_wid/16.0), (int32_t)ceil(t_hei/16.0), cs, fl);
22880 ssc_tile_hei_buf = zc_max(ssc_tile_hei_buf, t_hei);
22881 cursor_x += MsgStrings[msgstr].hspace + t_wid;
22882 return true;
22883 }
22884
22885 case MSGC_GOTOIFRAND:
22886 {
22887 int32_t odds = (int32_t)(grab_next_argument());
22888
22889 if(!odds || !(zc_oldrand()%odds))
22890 goto switched;
22891
22892 (void)grab_next_argument();
22893 return true;
22894 }
22895
22896 case MSGC_GOTOIFGLOBAL:
22897 {
22898 int32_t arg = (int32_t)grab_next_argument();
22899 int32_t d = zc_min(7,arg);
22900 int32_t s = ((get_currdmap())<<7) + get_currscr()-(DMaps[get_currdmap()].type==dmOVERW ? 0 : DMaps[get_currdmap()].xoff);
22901 arg = (int32_t)grab_next_argument();
22902
22903 if(game->screen_d[s][d] >= arg)
22904 goto switched;
22905
22906 (void)grab_next_argument();
22907 return true;
22908 }
22909
22910 case MSGC_CHANGEPORTRAIT:
22911 {
22912 return true; //not implemented
22913 }
22914
22915 case MSGC_GOTOIFCREEND:
22916 {
22917 int32_t dmap = (grab_next_argument()<<7); //dmap and screen may be transposed here.
22918 int32_t screen = grab_next_argument();
22919 int32_t reg = grab_next_argument();
22920 int32_t val = grab_next_argument();
22921 //int32_t nxtstr = grab_next_argument();
22922 if ( FFCore.get_screen_d(screen + dmap, reg) >= val )
22923 {
22924 goto switched;
22925 }
22926 (void)grab_next_argument();
22927 return true;
22928 }
22929
22930 case MSGC_GOTOIF:
22931 {
22932 int32_t it = (int32_t)grab_next_argument();
22933
22934 if(unsigned(it)<MAXITEMS && game->item[it])
22935 goto switched;
22936
22937 (void)grab_next_argument();
22938 return true;
22939 }
22940
22941 case MSGC_GOTOIFCTR:
22942 {
22943 if(game->get_counter(grab_next_argument())>=grab_next_argument())
22944 goto switched;
22945
22946 (void)grab_next_argument();
22947 return true;
22948 }
22949
22950 case MSGC_GOTOIFCTRPC:
22951 {
22952 int32_t counter = grab_next_argument();
22953 int32_t amount = (int32_t)(((grab_next_argument())/100)*game->get_maxcounter(counter));
22954
22955 if(game->get_counter(counter)>=amount)
22956 goto switched;
22957
22958 (void)grab_next_argument();
22959 return true;
22960 }
22961
22962 case MSGC_GOTOIFTRICOUNT:
22963 {
22964 if(TriforceCount() >= (int32_t)(grab_next_argument()))
22965 goto switched;
22966
22967 (void)grab_next_argument();
22968 return true;
22969 }
22970
22971 case MSGC_GOTOIFTRI:
22972 {
22973 int32_t lev = (int32_t)(grab_next_argument());
22974
22975 if(lev<MAXLEVELS && game->lvlitems[lev]&liTRIFORCE)
22976 goto switched;
22977
22978 (void)grab_next_argument();
22979 return true;
22980 }
22981
22982 case MSGC_SETUPMENU:
22983 {
22984 msg_menu_data[MNU_CURSOR_TILE] = grab_next_argument();
22985 msg_menu_data[MNU_CURSOR_CSET] = grab_next_argument();
22986 msg_menu_data[MNU_CURSOR_WID] = grab_next_argument();
22987 msg_menu_data[MNU_CURSOR_HEI] = grab_next_argument();
22988 msg_menu_data[MNU_CURSOR_FLIP] = grab_next_argument();
22989 return true;
22990 }
22991
22992 case MSGC_MENUCHOICE:
22993 {
22994 int32_t pos = grab_next_argument();
22995 int32_t upos = grab_next_argument();
22996 int32_t dpos = grab_next_argument();
22997 int32_t lpos = grab_next_argument();
22998 int32_t rpos = grab_next_argument();
22999 if(cursor_x+MsgStrings[msgstr].hspace + msg_menu_data[MNU_CURSOR_WID] > msg_w-msg_margins[right])
23000 {
23001 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23002 ssc_tile_hei = ssc_tile_hei_buf;
23003 ssc_tile_hei_buf = -1;
23004 cursor_y += thei + MsgStrings[msgstr].vspace;
23005 if(bottom_margin_clip()) break;
23006 cursor_x=msg_margins[left];
23007 }
23008
23009 menu_options[pos] = menu_choice(cursor_x, cursor_y, pos,
23010 upos, dpos, lpos, rpos);
23011
23012 ssc_tile_hei_buf = zc_max(ssc_tile_hei_buf, msg_menu_data[MNU_CURSOR_HEI]);
23013 cursor_x += MsgStrings[msgstr].hspace + msg_menu_data[MNU_CURSOR_WID];
23014 return true;
23015 }
23016
23017 case MSGC_RUNMENU:
23018 {
23019 msg_menu_data[MNU_CHOSEN] = 0;
23020 msg_menu_data[MNU_CAN_CONFIRM] = 0;
23021 if(menu_options.size() < 1)
23022 return true;
23023 do_run_menu = true;
23024 return true;
23025 }
23026
23027 case MSGC_GOTOMENUCHOICE:
23028 {
23029 int32_t choice = grab_next_argument();
23030 if(msg_menu_data[MNU_CHOSEN] == choice)
23031 goto switched;
23032 (void)grab_next_argument();
23033 return true;
23034 }
23035
23036 case MSGC_ENDSTRING:
23037 {
23038 do_end_str = true;
23039 return true;
23040 }
23041 case MSGC_WAIT_ADVANCE:
23042 {
23043 wait_advance = true;
23044 linkedmsgclk = 51;
23045 return true;
23046 }
23047 case MSGC_TRIGSECRETS:
23048 {
23049 bool perm = (bool)grab_next_argument();
23050 hidden_entrance(0, true, false, -8);
23051 if(perm)
23052 setmapflag(mSECRET);
23053 return true;
23054 }
23055 case MSGC_SETSCREENSTATE:
23056 {
23057 int32_t flag = int32_t(grab_next_argument());
23058 if(unsigned(flag)>=mMAXIND)
23059 {
23060 Z_error("SCC 133: Flag %d is invalid\n", flag);
23061 return true;
23062 }
23063 bool state = bool(grab_next_argument());
23064 if(state)
23065 setmapflag(1<<flag);
23066 else
23067 unsetmapflag(1<<flag,true);
23068 return true;
23069 }
23070 case MSGC_SETSCREENSTATER:
23071 {
23072 int32_t map = (int32_t)grab_next_argument();
23073 int32_t scrid = (int32_t)grab_next_argument();
23074 if(map < 1 || map > map_count)
23075 {
23076 Z_error("SCC 134: Map %d is invalid\n", map);
23077 return true;
23078 }
23079 if(unsigned(scrid)>=0x80)
23080 {
23081 Z_error("SCC 134: Screen %d is invalid\n", scrid);
23082 return true;
23083 }
23084
23085 int32_t flag = int32_t(grab_next_argument());
23086 if(unsigned(flag)>=mMAXIND)
23087 {
23088 Z_error("SCC 134: Flag %d is invalid\n", flag);
23089 return true;
23090 }
23091 bool state = bool(grab_next_argument());
23092 if(state)
23093 setmapflag(mapind(map,scrid),1<<flag);
23094 else
23095 unsetmapflag(mapind(map,scrid),1<<flag,true);
23096 return true;
23097 }
23098 switched:
23099 int32_t lev = (int32_t)(grab_next_argument());
23100 if(lev && get_bit(quest_rules, qr_SCC_GOTO_RESPECTS_CONTFLAG)
23101 && (MsgStrings[lev].stringflags & STRINGFLAG_CONT))
23102 {
23103 msgstr=lev;
23104 msgpos=msgptr=0;
23105 msgfont=setmsgfont();
23106 }
23107 else donewmsg(lev);
23108 msgptr--; // To counteract it being incremented after this routine is called.
23109 putprices(false);
23110 return true;
23111 }
23112
23113 683 return false;
23114 700 }
23115
23116 // Wraps the message string... probably.
23117 683 void wrapmsgstr(char *s3)
23118 {
23119 683 int32_t j=0;
23120
23121
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 587 times.
683 if(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP)
23122 {
23123
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 76 times.
96 if(msgspace)
23124 {
23125 20 char c = MsgStrings[msgstr].s[msgptr];
23126
3/6
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
20 if(c != ' ' && c >= 32 && c <= 126)
23127 {
23128
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 20 times.
97 for(int32_t k=0; MsgStrings[msgstr].s[msgptr+k] && MsgStrings[msgstr].s[msgptr+k] != ' '; k++)
23129 {
23130
2/4
✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 77 times.
77 if(MsgStrings[msgstr].s[msgptr+k] >= 32 && MsgStrings[msgstr].s[msgptr+k] <= 126) s3[j++] = MsgStrings[msgstr].s[msgptr+k];
23131 77 }
23132
23133 20 s3[j] = 0;
23134 20 msgspace = false;
23135 20 }
23136 else
23137 {
23138 s3[0] = c;
23139 s3[1] = 0;
23140 }
23141 20 }
23142 else
23143 {
23144 76 s3[0] = MsgStrings[msgstr].s[msgptr];
23145 76 s3[1] = 0;
23146
23147
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 19 times.
76 if(s3[0] == ' ') msgspace=true;
23148 }
23149 96 }
23150 else
23151 {
23152 587 s3[0] = MsgStrings[msgstr].s[msgptr];
23153 587 s3[1] = 0;
23154 }
23155 683 }
23156
23157 // Returns true if the pointer is at a string's
23158 // null terminator or a trailing space
23159 3293 bool atend(char const* str)
23160 {
23161 3293 int32_t i=0;
23162
23163
2/2
✓ Branch 0 taken 43930 times.
✓ Branch 1 taken 3293 times.
47223 while(str[i]==' ')
23164 43930 i++;
23165
23166 3293 return str[i]=='\0';
23167 }
23168
23169 66520 void putmsg()
23170 {
23171 66520 bool oldmargin = get_bit(quest_rules, qr_OLD_STRING_EDITOR_MARGINS)!=0;
23172
2/2
✓ Branch 0 taken 62173 times.
✓ Branch 1 taken 4347 times.
66520 if(!msgorig) msgorig=msgstr;
23173
23174
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 66520 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
66520 if(wait_advance && linkedmsgclk < 1)
23175 linkedmsgclk = 1;
23176
2/2
✓ Branch 0 taken 66123 times.
✓ Branch 1 taken 397 times.
66520 if(linkedmsgclk>0)
23177 {
23178
2/2
✓ Branch 0 taken 197 times.
✓ Branch 1 taken 200 times.
397 if(linkedmsgclk==1)
23179 {
23180
4/6
✓ Branch 0 taken 197 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 193 times.
197 if(do_end_str||cAbtn()||cBbtn())
23181 {
23182 4 do_end_str = false;
23183 4 linkedmsgclk = 0;
23184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(wait_advance)
23185 {
23186 wait_advance = false;
23187 }
23188 else
23189 {
23190 4 msgstr=MsgStrings[msgstr].nextstring;
23191
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
4 if(!msgstr && enqueued_str)
23192 {
23193 msgstr = enqueued_str;
23194 enqueued_str = 0;
23195 }
23196
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if(!msgstr)
23197 {
23198 1 msgfont=zfont;
23199
23200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(tmpscr->room!=rGRUMBLE)
23201 1 blockpath=false;
23202
23203 1 dismissmsg();
23204 1 goto disappear;
23205 }
23206
23207 3 donewmsg(msgstr);
23208 3 putprices(false);
23209 }
23210 3 }
23211 196 }
23212 else
23213 {
23214 200 --linkedmsgclk;
23215 }
23216 396 }
23217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66519 times.
66519 if(wait_advance) return; //Waiting for buttonpress
23218
23219
7/10
✓ Branch 0 taken 66519 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4332 times.
✓ Branch 3 taken 62187 times.
✓ Branch 4 taken 4332 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2093 times.
✓ Branch 7 taken 2239 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2093 times.
66519 if(!do_run_menu && (!msgstr || msgpos>=10000 || msgptr>=MsgStrings[msgstr].s.size() || bottom_margin_clip()))
23220 {
23221
2/2
✓ Branch 0 taken 2239 times.
✓ Branch 1 taken 62187 times.
64426 if(!msgstr)
23222 62187 msgorig=0;
23223
23224 64426 msg_active = false;
23225 64426 return;
23226 }
23227
23228 2093 msg_onscreen = true; // Now the message is onscreen (see donewmsg()).
23229
23230 char s3[145];
23231 int32_t tlength;
23232
23233 // Bypass the string with the B button!
23234
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2093 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2093 times.
2093 if(((cBbtn())&&(get_bit(quest_rules,qr_ALLOWMSGBYPASS))) || msgspeed==0)
23235 {
23236 //finish writing out the string
23237 while(msgptr<MsgStrings[msgstr].s.size() && !atend(MsgStrings[msgstr].s.c_str()+msgptr))
23238 {
23239 if(msgspeed && !(cBbtn() && get_bit(quest_rules,qr_ALLOWMSGBYPASS)))
23240 goto breakout; // break out if message speed was changed to non-zero
23241 else if(!do_run_menu && !doing_name_insert && !parsemsgcode())
23242 {
23243 if(bottom_margin_clip())
23244 break;
23245
23246 wrapmsgstr(s3);
23247
23248 if(MsgStrings[msgstr].s[msgptr]==' ')
23249 {
23250 tlength = msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]) + MsgStrings[msgstr].hspace;
23251
23252 if(cursor_x+tlength > (msg_w-msg_margins[right])
23253 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23254 ? true : strcmp(s3," ")!=0))
23255 {
23256 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23257 ssc_tile_hei = ssc_tile_hei_buf;
23258 ssc_tile_hei_buf = -1;
23259 cursor_y += thei + MsgStrings[msgstr].vspace;
23260 if(bottom_margin_clip()) break;
23261 cursor_x=msg_margins[left];
23262 }
23263
23264 char buf[2] = {0};
23265 sprintf(buf,"%c",MsgStrings[msgstr].s[msgptr]);
23266
23267 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23268
23269 cursor_x+=tlength;
23270 }
23271 else
23272 {
23273 tlength = text_length(msgfont, s3) + ((int32_t)strlen(s3)*MsgStrings[msgstr].hspace);
23274 if(cursor_x+tlength > (msg_w-msg_margins[right])
23275 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23276 ? true : strcmp(s3," ")!=0))
23277 {
23278 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23279 ssc_tile_hei = ssc_tile_hei_buf;
23280 ssc_tile_hei_buf = -1;
23281 cursor_y += thei + MsgStrings[msgstr].vspace;
23282 if(bottom_margin_clip()) break;
23283 cursor_x=msg_margins[left];
23284 }
23285
23286 sfx(MsgStrings[msgstr].sfx);
23287
23288 char buf[2] = {0};
23289 sprintf(buf,"%c",MsgStrings[msgstr].s[msgptr]);
23290
23291 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23292
23293 cursor_x += msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]);
23294 cursor_x += MsgStrings[msgstr].hspace;
23295 }
23296
23297 msgpos++;
23298 }
23299 if(do_run_menu)
23300 {
23301 if(runMenuCursor())
23302 {
23303 do_run_menu = false;
23304 }
23305 else break;
23306 }
23307 if(doing_name_insert)
23308 {
23309 if(*nameptr)
23310 {
23311 if(bottom_margin_clip())
23312 break;
23313
23314 char s3[9] = {0};
23315
23316 if(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP)
23317 {
23318 strcpy(s3, nameptr);
23319 }
23320 else
23321 {
23322 s3[0] = *nameptr;
23323 s3[1] = 0;
23324 }
23325
23326 tlength = text_length(msgfont, s3) + ((int32_t)strlen(s3)*MsgStrings[msgstr].hspace);
23327
23328 if(cursor_x+tlength > (msg_w-msg_margins[right])
23329 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23330 ? true : strcmp(s3," ")!=0))
23331 {
23332 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23333 ssc_tile_hei = ssc_tile_hei_buf;
23334 ssc_tile_hei_buf = -1;
23335 cursor_y += thei + MsgStrings[msgstr].vspace;
23336 if(bottom_margin_clip()) break;
23337 cursor_x=msg_margins[left];
23338 }
23339
23340 sfx(MsgStrings[msgstr].sfx);
23341
23342 char buf[2] = {0};
23343 sprintf(buf,"%c",*nameptr);
23344
23345 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23346
23347 cursor_x += msgfont->vtable->char_length(msgfont, *nameptr);
23348 cursor_x += MsgStrings[msgstr].hspace;
23349 ++nameptr;
23350 continue; //don't advance the msgptr, as the next char in it was not processed!
23351 }
23352 else doing_name_insert = false;
23353 }
23354 ++msgptr;
23355 if(do_end_str)
23356 goto strendcheck;
23357 if(wait_advance)
23358 return;
23359 if(atend(MsgStrings[msgstr].s.c_str()+msgptr))
23360 {
23361 if(MsgStrings[msgstr].nextstring)
23362 {
23363 if(MsgStrings[MsgStrings[msgstr].nextstring].stringflags & STRINGFLAG_CONT)
23364 {
23365 msgstr=MsgStrings[msgstr].nextstring;
23366 msgpos=msgptr=0;
23367 msgfont=setmsgfont();
23368 }
23369 }
23370 }
23371 }
23372
23373 if (!do_run_menu)
23374 {
23375 msgclk = 72;
23376 msgpos = 10000;
23377 }
23378 }
23379 else
23380 2093 {
23381 breakout:
23382
23383
6/6
✓ Branch 0 taken 1713 times.
✓ Branch 1 taken 380 times.
✓ Branch 2 taken 735 times.
✓ Branch 3 taken 978 times.
✓ Branch 4 taken 303 times.
✓ Branch 5 taken 432 times.
2093 if(((msgclk++)%(msgspeed+1)<msgspeed)&&((!cAbtn())||(!get_bit(quest_rules,qr_ALLOWFASTMSG))))
23384 1410 return;
23385 }
23386
23387 // Start writing the string
23388
2/2
✓ Branch 0 taken 666 times.
✓ Branch 1 taken 17 times.
700 if(msgptr == 0)
23389 {
23390
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 42 times.
59 while(MsgStrings[msgstr].s[msgptr]==' ')
23391 {
23392 42 tlength = msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]) + MsgStrings[msgstr].hspace;
23393
23394
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
42 if(cursor_x+tlength > (msg_w-msg_margins[right])
23395
1/6
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
42 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23396 ? 1 : strcmp(s3," ")!=0))
23397 {
23398 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23399 ssc_tile_hei = ssc_tile_hei_buf;
23400 ssc_tile_hei_buf = -1;
23401 cursor_y += thei + MsgStrings[msgstr].vspace;
23402 if(bottom_margin_clip()) break;
23403 cursor_x=msg_margins[left];
23404 }
23405
23406 42 cursor_x+=tlength;
23407 42 ++msgptr;
23408 42 ++msgpos;
23409
23410 // The "Continue From Previous" feature
23411
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 if(atend(MsgStrings[msgstr].s.c_str()+msgptr))
23412 {
23413 if(MsgStrings[msgstr].nextstring)
23414 {
23415 if(MsgStrings[MsgStrings[msgstr].nextstring].stringflags & STRINGFLAG_CONT)
23416 {
23417 msgstr=MsgStrings[msgstr].nextstring;
23418 msgpos=msgptr=0;
23419 msgfont=setmsgfont();
23420 }
23421 }
23422 }
23423 }
23424 17 }
23425
23426 reparsesinglechar:
23427 // Continue printing the string!
23428
2/4
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 683 times.
1366 if(!atend(MsgStrings[msgstr].s.c_str()+msgptr) && !bottom_margin_clip())
23429 {
23430
3/6
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 683 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 683 times.
683 if(!do_run_menu && !doing_name_insert && !parsemsgcode())
23431 {
23432 683 wrapmsgstr(s3);
23433
23434 683 tlength = text_length(msgfont, s3) + ((int32_t)strlen(s3)*MsgStrings[msgstr].hspace);
23435
23436
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
686 if(cursor_x+tlength > (msg_w-msg_margins[right])
23437
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 680 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
683 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23438 2 ? true : strcmp(s3," ")!=0))
23439 {
23440
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23441 3 ssc_tile_hei = ssc_tile_hei_buf;
23442 3 ssc_tile_hei_buf = -1;
23443 3 cursor_y += thei + MsgStrings[msgstr].vspace;
23444
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(bottom_margin_clip()) goto strendcheck;
23445 3 cursor_x=msg_margins[left];
23446 //if(space) s3[0]=0;
23447 3 }
23448
23449 683 sfx(MsgStrings[msgstr].sfx);
23450
23451 683 char buf[2] = {0};
23452 683 sprintf(buf,"%c",MsgStrings[msgstr].s[msgptr]);
23453
23454 683 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23455
23456 683 cursor_x += msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]);
23457 683 cursor_x += MsgStrings[msgstr].hspace;
23458 683 msgpos++;
23459 683 }
23460
1/2
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
683 if(do_end_str)
23461 goto strendcheck;
23462
1/2
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
683 if(wait_advance)
23463 {
23464 ++msgptr;
23465 return;
23466 }
23467
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 683 times.
683 else if(do_run_menu)
23468 {
23469 if(runMenuCursor())
23470 {
23471 do_run_menu = false;
23472 ++msgptr;
23473 goto reparsesinglechar;
23474 }
23475 }
23476
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 683 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
683 else if(doing_name_insert && *nameptr)
23477 {
23478 char s3[9] = {0};
23479
23480 if(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP)
23481 {
23482 strcpy(s3, nameptr);
23483 }
23484 else
23485 {
23486 s3[0] = *nameptr;
23487 s3[1] = 0;
23488 }
23489
23490 tlength = text_length(msgfont, s3) + ((int32_t)strlen(s3)*MsgStrings[msgstr].hspace);
23491
23492 if(cursor_x+tlength > (msg_w-msg_margins[right])
23493 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23494 ? true : strcmp(s3," ")!=0))
23495 {
23496 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23497 ssc_tile_hei = ssc_tile_hei_buf;
23498 ssc_tile_hei_buf = -1;
23499 cursor_y += thei + MsgStrings[msgstr].vspace;
23500 if(bottom_margin_clip()) goto strendcheck;
23501 cursor_x=msg_margins[left];
23502 }
23503
23504 sfx(MsgStrings[msgstr].sfx);
23505
23506 char buf[2] = {0};
23507 sprintf(buf,"%c",*nameptr);
23508
23509 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23510
23511 cursor_x += msgfont->vtable->char_length(msgfont, *nameptr);
23512 cursor_x += MsgStrings[msgstr].hspace;
23513 ++nameptr;
23514 }
23515 else
23516 {
23517 683 doing_name_insert = false;
23518 683 msgptr++;
23519
23520
2/2
✓ Branch 0 taken 666 times.
✓ Branch 1 taken 17 times.
683 if(atend(MsgStrings[msgstr].s.c_str()+msgptr))
23521 {
23522
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 3 times.
17 if(MsgStrings[msgstr].nextstring)
23523 {
23524
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(MsgStrings[MsgStrings[msgstr].nextstring].stringflags & STRINGFLAG_CONT)
23525 {
23526 msgstr=MsgStrings[msgstr].nextstring;
23527 msgpos=msgptr=0;
23528 msgfont=setmsgfont();
23529 }
23530 3 }
23531 17 }
23532
23533
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 46 times.
821 if(MsgStrings[msgstr].s.size() > unsigned(msgptr+1)
23534
1/2
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
683 && (MsgStrings[msgstr].s[msgptr]==' ')
23535
2/2
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 545 times.
683 && (MsgStrings[msgstr].s[msgptr+1]==' '))
23536 {
23537
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 1219 times.
1265 while(MsgStrings[msgstr].s[msgptr]==' ')
23538 {
23539 1219 msgspace = true;
23540 1219 tlength = msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]) + MsgStrings[msgstr].hspace;
23541
23542
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 58 times.
1278 if(cursor_x+tlength > (msg_w-msg_margins[right])
23543
4/6
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 1160 times.
✓ Branch 2 taken 59 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 58 times.
✗ Branch 5 not taken.
1219 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23544 1 ? true : strcmp(s3," ")!=0))
23545 {
23546
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23547 59 ssc_tile_hei = ssc_tile_hei_buf;
23548 59 ssc_tile_hei_buf = -1;
23549 59 cursor_y += thei + MsgStrings[msgstr].vspace;
23550
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 if(bottom_margin_clip()) break;
23551 59 cursor_x=msg_margins[left];
23552 59 }
23553
23554 1219 cursor_x+=tlength;
23555 1219 ++msgpos;
23556 1219 ++msgptr;
23557
23558
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 1069 times.
1219 if(atend(MsgStrings[msgstr].s.c_str()+msgptr))
23559 {
23560
2/2
✓ Branch 0 taken 760 times.
✓ Branch 1 taken 309 times.
1069 if(MsgStrings[msgstr].nextstring)
23561 {
23562
1/2
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
309 if(MsgStrings[MsgStrings[msgstr].nextstring].stringflags & STRINGFLAG_CONT)
23563 {
23564 msgstr=MsgStrings[msgstr].nextstring;
23565 msgpos=msgptr=0;
23566 msgfont=setmsgfont();
23567 }
23568 309 }
23569 1069 }
23570 }
23571 46 }
23572 }
23573 683 }
23574 strendcheck:
23575 // Done printing the string
23576
9/14
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 683 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 683 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 683 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 666 times.
✓ Branch 9 taken 17 times.
✓ Branch 10 taken 666 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 666 times.
✓ Branch 13 taken 17 times.
683 if(do_end_str || !doing_name_insert && !do_run_menu && (msgpos>=10000 || msgptr>=MsgStrings[msgstr].s.size() || bottom_margin_clip() || atend(MsgStrings[msgstr].s.c_str()+msgptr)) && !linkedmsgclk)
23577 {
23578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!do_end_str)
23579
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 while(parsemsgcode()); // Finish remaining control codes
23580
23581 // Go to next string, or make it disappear by going to string 0.
23582
5/6
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 13 times.
17 if(MsgStrings[msgstr].nextstring!=0 || get_bit(quest_rules,qr_MSGDISAPPEAR) || enqueued_str)
23583 {
23584 4 linkedmsgclk=do_end_str?1:51;
23585 4 }
23586
23587
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 3 times.
17 if(MsgStrings[msgstr].nextstring==0)
23588 {
23589
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
14 if(!get_bit(quest_rules,qr_MSGDISAPPEAR))
23590 13 {
23591 disappear:
23592 14 msg_active = false;
23593 14 Hero.finishedmsg();
23594 14 }
23595
23596
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if(repaircharge)
23597 {
23598 // if (get_bit(quest_rules,qr_REPAIRFIX)) {
23599 // fixed_door=true;
23600 // }
23601 game->change_drupy(-tmpscr[currscr<128?0:1].catchall);
23602 repaircharge = 0;
23603 }
23604
23605
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if(adjustmagic)
23606 {
23607 if(get_bit(quest_rules,qr_OLD_HALF_MAGIC))
23608 {
23609 if(game->get_magicdrainrate())
23610 game->set_magicdrainrate(1);
23611 }
23612 else if(game->get_magicdrainrate() > 1)
23613 {
23614 game->set_magicdrainrate(game->get_magicdrainrate()/2);
23615 }
23616 adjustmagic = false;
23617 sfx(WAV_SCALE);
23618 setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
23619 }
23620
23621
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if(learnslash)
23622 {
23623 game->set_canslash(1);
23624 learnslash = false;
23625 sfx(WAV_SCALE);
23626 setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
23627 }
23628 15 }
23629 18 }
23630 66520 }
23631
23632 197 int32_t message_more_y()
23633 {
23634 //Is the flag ticked, do we really want a message more y larger than 160?
23635
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 197 times.
✓ Branch 2 taken 197 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 197 times.
✗ Branch 5 not taken.
197 int32_t msgy=zc_min((zinit.msg_more_is_offset==0)?zinit.msg_more_y:zinit.msg_more_y+MsgStrings[msgstr].y ,160);
23636 197 msgy+=playing_field_offset;
23637 197 return msgy;
23638 }
23639
23640 /*** Collision detection & handling ***/
23641
23642 66437 void clear_script_one_frame_conditions()
23643 {
23644
2/2
✓ Branch 0 taken 143354 times.
✓ Branch 1 taken 66437 times.
209791 for(int32_t j=0; j<guys.Count(); j++)
23645 {
23646 143354 enemy *e = (enemy*)guys.spr(j);
23647
2/2
✓ Branch 0 taken 2293664 times.
✓ Branch 1 taken 143354 times.
2437018 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) e->hitby[q] = 0;
23648 143354 }
23649 66437 }
23650
23651 66427 void check_collisions()
23652 {
23653 66427 bool temp_hit = false;
23654
2/2
✓ Branch 0 taken 21693 times.
✓ Branch 1 taken 66427 times.
88120 for(int32_t i=0; i<Lwpns.Count(); i++)
23655 {
23656 21693 weapon *w = (weapon*)Lwpns.spr(i);
23657
23658
6/8
✓ Branch 0 taken 15938 times.
✓ Branch 1 taken 5755 times.
✓ Branch 2 taken 11959 times.
✓ Branch 3 taken 3979 times.
✓ Branch 4 taken 11959 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 11959 times.
21693 if(!(w->Dead()) && w->id!=wSword && w->id!=wHammer && w->id!=wWand)
23659 {
23660
2/2
✓ Branch 0 taken 11808 times.
✓ Branch 1 taken 20871 times.
32679 for(int32_t j=0; j<guys.Count(); j++)
23661 {
23662 20871 enemy *e = (enemy*)guys.spr(j);
23663
2/2
✓ Branch 0 taken 445 times.
✓ Branch 1 taken 20426 times.
20871 if ( !temp_hit ) e->hitby[HIT_BY_LWEAPON] = 0;
23664
23665
2/2
✓ Branch 0 taken 20439 times.
✓ Branch 1 taken 432 times.
20871 if(e->hit(w)) //boomerangs and such that last for more than a frame can write hitby[] for more than one frame,
23666 //because this only checks `if(dying || clk<0 || hclk>0 || superman)`
23667 {
23668 // !(e->stunclk)
23669 432 int32_t h = e->takehit(w);
23670
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
432 if (h == -1)
23671 {
23672 432 e->hitby[HIT_BY_LWEAPON] = i+1; temp_hit = true;
23673 432 e->hitby[HIT_BY_LWEAPON_UID] = w->script_UID;
23674 //e->hitby[HIT_BY_LWEAPON_FAMILY] = itemsbuf[w->parentid].family; //that would be the itemclass, not the weapon type!
23675 432 e->hitby[HIT_BY_LWEAPON_FAMILY] = w->id;
23676 //al_trace("npc->HitBy[] Parent Item is: %d /n", w->parentitem);
23677 //al_trace("npc->HitBy[] Parent ID is: %d /n", w->parentid);
23678 432 e->hitby[HIT_BY_LWEAPON_LITERAL_ID] = w->parentitem;
23679
23680 432 }
23681 //we may need to handle this in special cases. -Z
23682
23683 //if h == stun or ignore
23684
23685 //if e->stun > DEFAULT_STUN -1 || !e->stun
23686 //if the enemy wasn't stunned this round -- what a bitch, as the stun value is set before we check this
23687 ///! how about: if w->dead != bounce !
23688
23689 // NOT FOR PUBLIC RELEASE
23690 /*if(h==3) //Mirror shield
23691 {
23692 if (w->id==ewFireball || w->id==wRefFireball)
23693 {
23694 w->id=wRefFireball;
23695 switch(e->dir)
23696 {
23697 case up: e->angle += (PI - e->angle) * 2.0; break;
23698 case down: e->angle = -e->angle; break;
23699 case left: e->angle += ((-PI/2) - e->angle) * 2.0; break;
23700 case right: e->angle += (( PI/2) - e->angle) * 2.0; break;
23701 // TODO: the following. -L.
23702 case l_up: break;
23703 case r_up: break;
23704 case l_down: break;
23705 case r_down: break;
23706 }
23707 }
23708 else
23709 {
23710 w->id = ((w->id==ewMagic || w->id==wRefMagic || w->id==wMagic) ? wRefMagic : wRefBeam);
23711 w->dir ^= 1;
23712 if(w->dir&2)
23713 w->flip ^= 1;
23714 else
23715 w->flip ^= 2;
23716 }
23717 w->ignoreHero=false;
23718 }
23719 else*/
23720
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
432 if(h)
23721 {
23722
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
432 if(e->switch_hooked && w->family_class == itype_switchhook)
23723 w->onhit(false, e, -1);
23724 432 else w->onhit(false, e, h);
23725 432 }
23726
23727
1/2
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
432 if(h==2)
23728 {
23729 break;
23730 }
23731 432 }
23732
23733
2/2
✓ Branch 0 taken 20720 times.
✓ Branch 1 taken 151 times.
20871 if(w->Dead())
23734 {
23735 151 break;
23736 }
23737 20720 }
23738
23739 // Item flags added in 2.55:
23740 // BRang/HShot/Arrows ITEM_FLAG4 is "Pick up anything" (port of qr_BRANGPICKUP)
23741 // BRang/HShot ITEM_FLAG5 is "Drags Items" (port of qr_Z3BRANG_HSHOT)
23742 // Arrows ITEM_FLAG2 is "Picks up items" (inverse port of qr_Z3BRANG_HSHOT)
23743 // -V
23744
4/6
✓ Branch 0 taken 7820 times.
✓ Branch 1 taken 4139 times.
✓ Branch 2 taken 7820 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 7820 times.
11959 if(w->id == wBrang || w->id == wHookshot || w->id == wArrow)
23745 {
23746 4139 int32_t itype, pitem = w->parentitem;
23747
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4139 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4139 switch(w->id)
23748 {
23749 4139 case wBrang: itype = itype_brang; break;
23750 case wArrow: itype = itype_arrow; break;
23751 case wHookshot:
23752 itype = (w->family_class == itype_switchhook ? itype_switchhook :itype_hookshot);
23753 break;
23754 }
23755
1/2
✓ Branch 0 taken 4139 times.
✗ Branch 1 not taken.
4139 if(pitem < 0) pitem = current_item_id(itype);
23756
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4139 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4139 if(w->id == wHookshot && w->family_class == itype_switchhook && (itemsbuf[pitem].flags & ITEM_FLAG9))
23757 { //Swap with item
23758 for(int32_t j=0; j<items.Count(); j++)
23759 {
23760 if(items.spr(j)->hit(w))
23761 {
23762 item *theItem = ((item*)items.spr(j));
23763 bool priced = theItem->PriceIndex >-1;
23764 bool isKey = itemsbuf[theItem->id].family==itype_key||itemsbuf[theItem->id].family==itype_lkey;
23765 if(!theItem->fallclk && !theItem->drownclk && ((theItem->pickup & ipTIMER && theItem->clk2 >= 32)
23766 || (((itemsbuf[w->parentitem].flags & ITEM_FLAG4)||(theItem->pickup & ipCANGRAB)||((itemsbuf[w->parentitem].flags & ITEM_FLAG7)&&isKey)) && !priced && !(theItem->pickup & ipDUMMY))))
23767 {
23768 if(!Hero.switchhookclk)
23769 {
23770 hooked_combopos = -1;
23771 hooked_layerbits = 0;
23772 switching_object = theItem;
23773 theItem->switch_hooked = true;
23774 w->misc = 2;
23775 w->step = 0;
23776 theItem->clk2=256;
23777 Hero.doSwitchHook(game->get_switchhookstyle());
23778 if(QMisc.miscsfx[sfxSWITCHED])
23779 sfx(QMisc.miscsfx[sfxSWITCHED],int32_t(w->x));
23780 }
23781 }
23782 }
23783 }
23784 }
23785
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4139 times.
✓ Branch 2 taken 3878 times.
✓ Branch 3 taken 3878 times.
✓ Branch 4 taken 4139 times.
✓ Branch 5 taken 3878 times.
4139 else if((w->id==wArrow&&itemsbuf[pitem].flags & ITEM_FLAG2)||(w->id!=wArrow&&!(itemsbuf[pitem].flags & ITEM_FLAG5)))//An arrow with "Picks up items" or a BRang/HShot without "Drags items"
23786 {
23787
2/2
✓ Branch 0 taken 709 times.
✓ Branch 1 taken 3878 times.
4587 for(int32_t j=0; j<items.Count(); j++)
23788 {
23789
2/2
✓ Branch 0 taken 661 times.
✓ Branch 1 taken 48 times.
709 if(items.spr(j)->hit(w))
23790 {
23791 48 item *theItem = ((item*)items.spr(j));
23792 48 bool priced = theItem->PriceIndex >-1;
23793
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 bool isKey = itemsbuf[theItem->id].family==itype_key||itemsbuf[theItem->id].family==itype_lkey;
23794
4/8
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 31 times.
79 if(!theItem->fallclk && !theItem->drownclk && ((theItem->pickup & ipTIMER && theItem->clk2 >= 32)
23795
4/6
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 31 times.
48 || (((itemsbuf[pitem].flags & ITEM_FLAG4)||(theItem->pickup & ipCANGRAB)||((itemsbuf[pitem].flags & ITEM_FLAG7)&&isKey))&& !priced)))
23796 {
23797
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
79 if(itemsbuf[theItem->id].collect_script)
23798 {
23799 ZScriptVersion::RunScript(SCRIPT_ITEM, itemsbuf[theItem->id].collect_script, theItem->id & 0xFFF);
23800 }
23801
23802 17 Hero.checkitems(j);
23803 17 }
23804 48 }
23805 709 }
23806 3878 }
23807
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
8017 else if(w->id!=wArrow) //A BRang/HShot with "Drags Items"
23808 {
23809
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 for(int32_t j=0; j<items.Count(); j++)
23810 {
23811 if(items.spr(j)->hit(w))
23812 {
23813 item *theItem = ((item*)items.spr(j));
23814 bool priced = theItem->PriceIndex >-1;
23815 bool isKey = itemsbuf[theItem->id].family==itype_key||itemsbuf[theItem->id].family==itype_lkey;
23816 if(!theItem->fallclk && !theItem->drownclk && ((theItem->pickup & ipTIMER && theItem->clk2 >= 32)
23817 || (((itemsbuf[pitem].flags & ITEM_FLAG4)||(theItem->pickup & ipCANGRAB)||((itemsbuf[pitem].flags & ITEM_FLAG7)&&isKey)) && !priced && !(theItem->pickup & ipDUMMY))))
23818 {
23819 int32_t pickup = theItem->pickup;
23820 int32_t id2 = theItem->id;
23821 int32_t pstr = theItem->pstring;
23822 int32_t pstr_flags = theItem->pickup_string_flags;
23823
23824 std::vector<int32_t> &ev = FFCore.eventData;
23825 ev.clear();
23826 ev.push_back(id2*10000);
23827 ev.push_back(pickup*10000);
23828 ev.push_back(pstr*10000);
23829 ev.push_back(pstr_flags*10000);
23830 ev.push_back(0);
23831 ev.push_back(theItem->getUID());
23832 ev.push_back(GENEVT_ICTYPE_RANGED_DRAG*10000);
23833 ev.push_back(w->getUID());
23834
23835 throwGenScriptEvent(GENSCR_EVENT_COLLECT_ITEM);
23836 bool nullify = ev[4] != 0;
23837 if(nullify) continue;
23838 if(w->id == wBrang)
23839 {
23840 w->onhit(false);
23841 }
23842
23843 if(w->dragging==-1)
23844 {
23845 w->dead=1;
23846 theItem->clk2=256;
23847 w->dragging=j;
23848 theItem->is_dragged = true;
23849 }
23850 }
23851 }
23852 }
23853 261 }
23854 4139 }
23855 11959 }
23856 21693 }
23857 66427 }
23858
23859 66437 void dragging_item()
23860 {
23861
2/2
✓ Branch 0 taken 22166 times.
✓ Branch 1 taken 66437 times.
88603 for(int32_t i=0; i<Lwpns.Count(); i++)
23862 {
23863 22166 weapon *w = (weapon*)Lwpns.spr(i);
23864
23865
4/4
✓ Branch 0 taken 17949 times.
✓ Branch 1 taken 4217 times.
✓ Branch 2 taken 21906 times.
✓ Branch 3 taken 260 times.
22166 if((w->id == wBrang || w->id==wHookshot)&&itemsbuf[w->parentitem].flags & ITEM_FLAG5)//ITEM_FLAG5 is a port for qr_Z3BRANG_HSHOT
23866 {
23867
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 260 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
260 if(w->dragging>=0 && w->dragging<items.Count())
23868 {
23869 item* dragItem = (item*)items.spr(w->dragging);
23870 dragItem->x=w->x;
23871 dragItem->y=w->y;
23872
23873 // Drag the Fairy enemy as well as the Fairy item
23874 int32_t id = dragItem->id;
23875
23876 if(itemsbuf[id].family ==itype_fairy && itemsbuf[id].misc3)
23877 {
23878 movefairynew2(w->x,w->y,*dragItem);
23879 }
23880 }
23881 260 }
23882 22166 }
23883 66437 }
23884
23885 3 int32_t more_carried_items()
23886 {
23887 3 int32_t hasmorecarries = 0;
23888
23889
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for(int32_t i=0; i<items.Count(); i++)
23890 {
23891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(((item*)items.spr(i))->pickup & ipENEMY)
23892 {
23893 3 hasmorecarries++;
23894 3 }
23895 3 }
23896
23897 3 return hasmorecarries;
23898 }
23899
23900 // messy code to do the enemy-carrying-the-item thing
23901 66437 void roaming_item()
23902 {
23903
4/4
✓ Branch 0 taken 754 times.
✓ Branch 1 taken 65683 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 751 times.
66437 if(!(hasitem&(4|2)) || !loaded_enemies)
23904 65686 return;
23905
23906 // All enemies already dead upon entering a room?
23907
1/2
✓ Branch 0 taken 751 times.
✗ Branch 1 not taken.
751 if(guys.Count()==0)
23908 {
23909 return;
23910 }
23911
23912 // Lost track of the carrier?
23913
3/6
✓ Branch 0 taken 751 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 751 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 751 times.
✗ Branch 5 not taken.
751 if(guycarryingitem<0 || guycarryingitem>=guys.Count() ||
23914 751 !((enemy*)guys.spr(guycarryingitem))->itemguy)
23915 {
23916 guycarryingitem=-1;
23917 for(int32_t j=0; j<guys.Count(); j++)
23918 {
23919 if(((enemy*)guys.spr(j))->itemguy)
23920 {
23921 guycarryingitem=j;
23922 break;
23923 }
23924 }
23925 }
23926
23927
2/2
✓ Branch 0 taken 748 times.
✓ Branch 1 taken 3 times.
751 if(hasitem&4)
23928 {
23929 3 guycarryingitem = -1;
23930
23931
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 3 times.
18 for(int32_t i=0; i<guys.Count(); i++)
23932 {
23933
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3 times.
15 if(((enemy*)guys.spr(i))->itemguy)
23934 {
23935 3 guycarryingitem = i;
23936 3 }
23937 15 }
23938
23939
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(guycarryingitem == -1) //This happens when "default enemies" such as
23940 {
23941 return; //eSHOOTFBALL are alive but enemies from the list
23942 } //are not. Defer to HeroClass::checkspecial().
23943
23944 3 int32_t Item=tmpscr->item;
23945
23946 3 hasitem &= ~4;
23947
23948
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if((!getmapflag(mITEM) || (tmpscr->flags9&fITEMRETURN)) && (tmpscr->hasitem != 0))
23949 {
23950 6 additem(0,0,Item,ipENEMY+ipONETIME+ipBIGRANGE
23951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 + (((tmpscr->flags3&fHOLDITEM) || (itemsbuf[Item].family==itype_triforcepiece)) ? ipHOLDUP : 0)
23952 );
23953 3 hasitem |= 2;
23954 3 }
23955 else
23956 {
23957 return;
23958 }
23959 3 }
23960
23961
2/2
✓ Branch 0 taken 751 times.
✓ Branch 1 taken 751 times.
1502 for(int32_t i=0; i<items.Count(); i++)
23962 {
23963
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 751 times.
751 if(((item*)items.spr(i))->pickup&ipENEMY)
23964 {
23965
2/2
✓ Branch 0 taken 327 times.
✓ Branch 1 taken 424 times.
751 if(get_bit(quest_rules,qr_HIDECARRIEDITEMS))
23966 {
23967 424 items.spr(i)->x = -128; // Awfully inelegant, innit?
23968 424 items.spr(i)->y = -128;
23969 424 }
23970
2/4
✓ Branch 0 taken 327 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 327 times.
327 else if(guycarryingitem>=0 && guycarryingitem<guys.Count())
23971 {
23972
1/2
✓ Branch 0 taken 327 times.
✗ Branch 1 not taken.
327 if (!get_bit(quest_rules, qr_BROKEN_ITEM_CARRYING))
23973 {
23974 if (get_bit(quest_rules, qr_ENEMY_DROPS_USE_HITOFFSETS))
23975 {
23976 items.spr(i)->x = guys.spr(guycarryingitem)->x+guys.spr(guycarryingitem)->hxofs+(guys.spr(guycarryingitem)->hxsz/2)-8;
23977 items.spr(i)->y = guys.spr(guycarryingitem)->y+guys.spr(guycarryingitem)->hyofs+(guys.spr(guycarryingitem)->hysz/2)-10;
23978 }
23979 else
23980 {
23981 if(guys.spr(guycarryingitem)->extend >= 3)
23982 {
23983 items.spr(i)->x = guys.spr(guycarryingitem)->x+(guys.spr(guycarryingitem)->txsz-1)*8;
23984 items.spr(i)->y = guys.spr(guycarryingitem)->y-2+(guys.spr(guycarryingitem)->tysz-1)*8;
23985 }
23986 else
23987 {
23988 items.spr(i)->x = guys.spr(guycarryingitem)->x;
23989 items.spr(i)->y = guys.spr(guycarryingitem)->y - 2;
23990 }
23991 }
23992 items.spr(i)->z = guys.spr(guycarryingitem)->z;
23993 items.spr(i)->fakez = guys.spr(guycarryingitem)->fakez;
23994 }
23995 else
23996 {
23997 327 items.spr(i)->x = guys.spr(guycarryingitem)->x;
23998 327 items.spr(i)->y = guys.spr(guycarryingitem)->y - 2;
23999 327 items.spr(i)->fakez = guys.spr(guycarryingitem)->fakez;
24000 }
24001 327 }
24002 751 }
24003 751 }
24004 66437 }
24005
24006 bool enemy::IsBigAnim()
24007 {
24008 return (anim == a2FRMB || anim == a4FRM8EYEB || anim == a4FRM4EYEB
24009 || anim == a4FRM8DIRFB || anim == a4FRM4DIRB || anim == a4FRM4DIRFB
24010 || anim == a4FRM8DIRB);
24011 }
24012
24013 const char *old_guy_string[OLDMAXGUYS] =
24014 {
24015 "(None)","Abei","Ama","Merchant","Moblin","Fire","Fairy","Goriya","Zelda","Abei 2","Empty","","","","","","","","","",
24016 // 020
24017 "Octorok (L1, Slow)","Octorok (L2, Slow)","Octorok (L1, Fast)","Octorok (L2, Fast)","Tektite (L1)",
24018 // 025
24019 "Tektite (L2)","Leever (L1)","Leever (L2)","Moblin (L1)","Moblin (L2)",
24020 // 030
24021 "Lynel (L1)","Lynel (L2)","Peahat (L1)","Zora","Rock",
24022 // 035
24023 "Ghini (L1, Normal)","Ghini (L1, Phantom)","Armos","Keese (CSet 7)","Keese (CSet 8)",
24024 // 040
24025 "Keese (CSet 9)","Stalfos (L1)","Gel (L1, Normal)","Zol (L1, Normal)","Rope (L1)",
24026 // 045
24027 "Goriya (L1)","Goriya (L2)","Trap (4-Way)","Wall Master","Darknut (L1)",
24028 // 050
24029 "Darknut (L2)","Bubble (Sword, Temporary Disabling)","Vire (Normal)","Like Like","Gibdo",
24030 // 055
24031 "Pols Voice (Arrow)","Wizzrobe (Teleporting)","Wizzrobe (Floating)","Aquamentus (Facing Left)","Moldorm",
24032 // 060
24033 "Dodongo","Manhandla (L1)","Gleeok (1 Head)","Gleeok (2 Heads)","Gleeok (3 Heads)",
24034 // 065
24035 "Gleeok (4 Heads)","Digdogger (1 Kid)","Digdogger (3 Kids)","Digdogger Kid (1)","Digdogger Kid (2)",
24036 // 070
24037 "Digdogger Kid (3)","Digdogger Kid (4)","Gohma (L1)","Gohma (L2)","Lanmola (L1)",
24038 // 075
24039 "Lanmola (L2)","Patra (L1, Big Circle)","Patra (L1, Oval)","Ganon","Stalfos (L2)",
24040 // 080
24041 "Rope (L2)","Bubble (Sword, Permanent Disabling)","Bubble (Sword, Re-enabling)","Shooter (Fireball)","Item Fairy ",
24042 // 085
24043 "Fire","Octorok (Magic)", "Darknut (Death Knight)", "Gel (L1, Tribble)", "Zol (L1, Tribble)",
24044 // 090
24045 "Keese (Tribble)", "Vire (Tribble)", "Darknut (Splitting)", "Aquamentus (Facing Right)", "Manhandla (L2)",
24046 // 095
24047 "Trap (Horizontal, Line of Sight)", "Trap (Vertical, Line of Sight)", "Trap (Horizontal, Constant)", "Trap (Vertical, Constant)", "Wizzrobe (Fire)",
24048 // 100
24049 "Wizzrobe (Wind)", "Ceiling Master ", "Floor Master ", "Patra (BS Zelda)", "Patra (L2)",
24050 // 105
24051 "Patra (L3)", "Bat", "Wizzrobe (Bat)", "Wizzrobe (Bat 2) ", "Gleeok (Fire, 1 Head)",
24052 // 110
24053 "Gleeok (Fire, 2 Heads)", "Gleeok (Fire, 3 Heads)","Gleeok (Fire, 4 Heads)", "Wizzrobe (Mirror)", "Dodongo (BS Zelda)",
24054 // 115
24055 "Dodongo (Fire) ","Trigger", "Bubble (Item, Temporary Disabling)", "Bubble (Item, Permanent Disabling)", "Bubble (Item, Re-enabling)",
24056 // 120
24057 "Stalfos (L3)", "Gohma (L3)", "Gohma (L4)", "NPC 1 (Standing) ", "NPC 2 (Standing) ",
24058 // 125
24059 "NPC 3 (Standing) ", "NPC 4 (Standing) ", "NPC 5 (Standing) ", "NPC 6 (Standing) ", "NPC 1 (Walking) ",
24060 // 130
24061 "NPC 2 (Walking) ", "NPC 3 (Walking) ", "NPC 4 (Walking) ", "NPC 5 (Walking) ", "NPC 6 (Walking) ",
24062 // 135
24063 "Boulder", "Goriya (L3)", "Leever (L3)", "Octorok (L3, Slow)", "Octorok (L3, Fast)",
24064 // 140
24065 "Octorok (L4, Slow)", "Octorok (L4, Fast)", "Trap (8-Way) ", "Trap (Diagonal) ", "Trap (/, Constant) ",
24066 // 145
24067 "Trap (/, Line of Sight) ", "Trap (\\, Constant) ", "Trap (\\, Line of Sight) ", "Trap (CW, Constant) ", "Trap (CW, Line of Sight) ",
24068 // 150
24069 "Trap (CCW, Constant) ", "Trap (CCW, Line of Sight) ", "Wizzrobe (Summoner)", "Wizzrobe (Ice) ", "Shooter (Magic)",
24070 // 155
24071 "Shooter (Rock)", "Shooter (Spear)", "Shooter (Sword)", "Shooter (Fire)", "Shooter (Fire 2)",
24072 // 160
24073 "Bombchu", "Gel (L2, Normal)", "Zol (L2, Normal)", "Gel (L2, Tribble)", "Zol (L2, Tribble)",
24074 // 165
24075 "Tektite (L3) ", "Spinning Tile (Combo)", "Spinning Tile (Enemy Sprite)", "Lynel (L3) ", "Peahat (L2) ",
24076 // 170
24077 "Pols Voice (Magic) ", "Pols Voice (Whistle) ", "Darknut (Mirror) ", "Ghini (L2, Fire) ", "Ghini (L2, Magic) ",
24078 // 175
24079 "Grappler Bug (HP) ", "Grappler Bug (MP) "
24080 };
24081
24082 /*** end of guys.cc ***/
24083
24084